Jasypt with spring framework - spring

I'm trying to set up jasypt to have passwords in .properties files encrypted.
I don't need to encrypt anything on runtime, only decrypt.
My passwords are already encripted in the .properties file like this: some.pass=ENC(aFX0/gUNUbk1TMX0qddowrq23Htqr5Kh8mTwqmx1KA/n3tE=)
After researching I found that I could achieve this with some steps:
-Adding the Jasypt dependency on pom.xml
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.3</version>
</dependency>
Then there are two approaches (I think):
1 Use and environment variable (with the decription key) that is set on startup:
-Djasypt.encryptor.password=decryptionKey
2 Use beans:
<bean id="environmentVariablesConfiguration"
class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="passwordEnvName" value="decryptionKey" />
</bean>
<bean id="propertyConfigurer"
class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>/WEB-INF/classes/application.properties</value>
</list>
</property>
</bean>
My question is how do I actually decrypt my passwords with either one of these approaches. Can I simply use #Value("${some.pass}") String decryptedPassword; ?
I'm quite confused because most of the content that I searching is related to spring boot which is not my case.
Thanks in advance for any help

The solution was addind the pom dependency in pom.xml, then add to the VMoptions in Intellij an environment variable -DAPP_ENCRYPTION_PASSWORD=mykey.
Then I added the following beans:
<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWITHMD5ANDDES" />
<property name="passwordSysPropertyName" value="APP_ENCRYPTION_PASSWORD" />
</bean>
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config" ref="environmentVariablesConfiguration" />
</bean>
and then another bean for each environment, for example, for development:
<beans profile="development">
<bean class="org.jasypt.spring4.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>/WEB-INF/config/config.properties</value>
<value>/WEB-INF/config/config.development.properties</value>
</list>
</property>
</bean>
<bean id="somethingService" class="doesnt.matter.common.someth.services.api.v1.Something"
p:serverUrl="http://something"
p:rest-ref="restOperations"
p:encryptLoginRequest="true"
p:encryptTokenRequest="true"
p:urlEncoding="ISO-8859-1"
/>
</beans>
where inside the property name="locations" tag I listed every file where encrypted passwords could be found.
Then, in those files I put the encrypted passwords, using this online tool
https://www.devglan.com/online-tools/jasypt-online-encryption-decryption.
for example, in my config.properties file I have a password like:
some.password=ENC(balrcbxgktzeskjvn==)
Finally, in the file where I use the password, I used the #Value annotation like this:
#Value("${some.password}")
private String hiddenPass;

Related

spring replace bean name in config file with value from property file

I have a bean config file as follows
<bean id="myFactory" class="com.public.Factory">
<property name="dataSourceAdaptor" ref="${value.from.property file}Adaptor" />
</bean>
How do i achieve this.
I added the following to top of the config file
<util:properties id="myProperties" location="classpath:app.properties"/>
and then tried to refer to the value using ${} but i get an error stating ${value.from.property file}Adaptor is not a valid bean
I cannot put the whole name (xyzAdaptor) in the property file as the value in the property file is an institution and there are multiple adaptors for each institution.
for example xzyDisplayAdaptor, xyzProductAdaptor, xyzDatasourceAdaptor
The xyz client can change to say abc client and i want to be able to change the value in property file to abc and all the abc related beans will be injected.
The util:properties tag is used to create an instance of java.util.Properties. I think what you need is a PropertyPlaceholderConfigurer.
e.g.,
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" scope="singleton">
<property name="searchSystemEnvironment" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:app.properties</value>
</list>
</property>
</bean>
Try this with Spel:
<util:properties id="myProperties" location="classpath:app.properties"/>
<bean id="myFactory" class="com.public.Factory">
<property name="dataSourceAdaptor" ref="#{'${value.from.property file}'+'Adaptor'}" />
</bean>

Several PropertyPlaceholderConfigurers with spring

I have a strange problem with my spring bean definition. My application is a multi-module thing.
At the moment I have a project named core-lib which has a spring.xml file defining a PropertyPlaceholderConfigurer like this:
<bean id="corePropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="10" />
<property name="locations">
<list>
<!-- default properties files containing ALL possible properties -->
<value>classpath:default.connection.properties</value>
<value>classpath:default.mq.properties</value>
<!-- installation specific, optional properties file containing overridden properties -->
<value>classpath:connection.properties</value>
<value>classpath:mq.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
Second I have a depending project which has its own spring.xml file including the one from the core-lib project. Moreover it defines a second PropertyPlaceholderConfigurer like this:
<!-- import configuration from service layer -->
<import resource="classpath:spring.xml"/>
<bean id="commPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="20" />
<property name="locations">
<list>
<!-- properties files containing ALL possible properties -->
<value>classpath:processing.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
Now I have the behavior that a bean defined in this second spring PlaceholderConfigurer can't be instantiated due to missing properties:
BeanDefinitionStoreException: Invalid bean definition with name 'commServer' defined in class path resource [comm-server.spring.xml]: Could not resolve placeholder 'comm.server.CommServer.port'
If I set a breakpoint in the PropertyPlaceholderConfigurer class it only get's triggered for the first bean instance and never for the second. Has anyone had a similar setup and can give me some advice?
Thanks,
Sebastian
There is a more comfortable way by defining a new placeholder prefix and suffix:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:configuration.properties</value>
</property>
<property name="placeholderPrefix" value="myprefix{" />
<property name="placeholderSuffix" value="}" />
</bean>
Found here: http://javalibs.blogspot.co.at/2008/04/java-spring-framework-multiple.html
OK I resolved that myself, although I do not understand why this is working so strange.
I have defined a different prefix in the second placeholder (?{ instead of ${) and now its working. I had expected that this would work without any special prefixes...

deployment for different environments with maven and spring

I've got two properties files:
environment.properties:
- project.host.db3.database.name=oracle
application.properties:
- database.name=${project.host.db3.database.name}
The first one represents the environment variables and the second one the properties to be used in a spring project, in this configuration i try to set the environment.properties but of course it doesn't work:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:environment.properties" />
</property>
</bean>
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
<!-- bean using database.name -->
Is it doable?, and if not, how do people have agnostic properties in their projects (like database.name), and only one file (war, jar, etc.) to be deployed?
Well, it seems it's doable for beans xml defined as long as you define your properties it like this:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
But if you ever try to access the properties from a servlet:
this.getClass().getClassLoader().getResourceAsStream("application.properties");
chances are you get this:
bad port configuration: ${project.host.db3.database.port}
java.lang.NumberFormatException: For input string: "${project.host.db3.database.port}"
In answer to yorkw, now i can have the same war to be deployed in several environments and configure the host with -Denvironment=development, so i can deploy a properties file for development, production, etc. and simply use:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:**${environment}/**environment.properties" />
</property>
</bean>
Otherwise i should have the application.properties substituted before deployment for every environment. I'm sure there are better solutions than this.

<jee:jndi-lookup default-value and the use of classpath

I am really stuck on this one... Help! :)
I am using j2ee:jndi lookup for a property file. The following works fine:
<bean class="org.springframework.core.io.FileSystemResource">
<constructor-arg>
<jee:jndi-lookup id="myProps" jndi-name="myProps" resource-ref="true" />
</constructor-arg>
</bean>
However, I want to handle the case where the jndi lookup fails but will fall back on a default file located in WEB-INF/classes folder. If I use the default-value as below, the webapp throws an exception complaining that it cannot find the file "classpath:myprops.properties"
<bean class="org.springframework.core.io.FileSystemResource">
<constructor-arg>
<jee:jndi-lookup id="myProps" jndi-name="myProps" resource-ref="true"
default-value="classpath:myprops.properties" />
</constructor-arg>
</bean>
However, if I hard-code a specific path for default-value, then it works fine, but that is unacceptable as a final solution.
Thus, my issue is how to use "classpath:" so that it gets properly resolved?
This is the overall usage I'm employing:
<bean id="authServerProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="ignoreResourceNotFound" value="true"/>
<property name="location">
<bean class="org.springframework.core.io.FileSystemResource">
<constructor-arg>
<jee:jndi-lookup id="myProps" jndi-name="myProps" resource-ref="true"
default-value="classpath:myprops.properties" />
</constructor-arg>
</bean>
</property>
.....
</bean>
Let Spring use its built-in PropertyEditor support to decide on the type of resource, rather than supplying an explicit FileSystemResource bean as this won't work with classpath resources (it needs to be configured with a path on the file system). Instead you should use something like
<bean id="authServerProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="ignoreResourceNotFound" value="true"/>
<property name="location" ref="myProps" />
</bean>
<jee:jndi-lookup id="myProps" jndi-name="myProps" resource-ref="true"
default-value="classpath:myprops.properties"/>
Here we are setting the location to be a string value and allowing Spring to convert that to the appropriate resource type, so if you have
<env-entry>
<env-entry-name>myProps</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>file:///Users/something/myProps.properties</env-entry-value>
</env-entry>
in your web.xml, it will use a UrlResource with the given file URL, otherwise it will create a ClasspathResource to look for the file myprops.properties.

Read property file outside war using spring

enter code hereI have a property file placed in the etc folder. "myapplication.properties" and few other property files in each sub module.. i am try to do the following
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="searchContextAttributes" value="true"/>
<property name="contextOverride" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>${config}</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
I am trying to do mvn -Dconfig=~/my.properties jetty:run
The properties are read from application.properties but not for config..
While running application i get the ${jdbc.url} not correct .. This url is present in my.properties ..
How can this be achieved ?
Thanks
This is what I had, to run it
<bean id="placeholderConfigConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:${config}" />
</bean>
And add -Dconfig=/var//my.properties in the MAVEN_OPTS.. and did mvn jetty:run
Another one line solution I found.. instead of making verbose configuration just do
<context:property-placeholder location="file:${config}"/>
I think this feature becomes available in spring 3.1 via the new Environment abstraction. See the following spring blog for details:
http://blog.springsource.com/2011/02/15/spring-3-1-m1-unified-property-management/.
If spring 3.1 is not an option you can hard-code the filename and path in the spring xml configuration file to some well-known location and then developers can symlink against it.

Resources