Spring application.properties not able to reference encrypted keys within files - spring

So I have an application.properties file that is set to be encrypted during the initialization of the Spring app. The keys to be encrypted are mentioned during initialization and the mentioned ones are all successfully encrypted.
For example -
application.properties
encrypt.keys=password1
password1=abcd123
password2=${password1}
After the app is run, password1 is successfully encrypted, can be called from a method and be decrypted properly. However, when the same function calls password2, it returns a null value.
Any help explaining why this is happening would be greatly appreciated. Thanks.

Related

How to initialize Spring Boot security config with default username/password but not crash on second run?

Following the topical guide here and adding a BCrypt password encoder based on Baeldung's example here I have configured my Spring Boot application to use my database (set up separately, not auto-generated by an ORM or something) as its source of user details for authentication. This part of my security configuration (here) looks like this:
#Override
public void configure(AuthenticationManagerBuilder builder) throws Exception {
builder .jdbcAuthentication()
.dataSource(dataSource)
.withUser(User.withUsername("admin").password(passwordEncoder().encode("pass")).roles("SUPER"));
logger.debug("Configured app to use JDBC authentication with default database.");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
On the first run, this works, creating a user called 'admin' with a hashed password and the specified role in the database. (This is a PostgreSQL database for what it's worth.) However, if I try to run the app again, it fails to start, crashing because it tried to create the same user again and got a duplicate primary key error.
What I'd like: I'd like Spring Boot to create the default user if it doesn't already exist, skip over it if one already exists.
Why: It is necessary to be able to log in to a newly initialized copy of the application, sometimes restarting several times, for testing and for experimentation on the developer's machine. My "production" database should already have an 'admin' login and the app should not overwrite it, or crash because it cannot.
My question, therefore, is: How can I initialize a default user in Spring Boot's jdbcAuthentication configuration in such a way that Spring Boot won't crash if the username already exists?
Alternatively: If I could INSERT a default user into the database with SQL when the database is spun up, I wouldn't need to do it in the Spring Boot configuration. But I don't know how to hash a password in an INSERT statement in a way that matches Spring Boot's hashing.
PS: I have another issue with my new configuration breaking some automated test classes (see the other question if interested).
You can use the alternative solution that you have thought using the option .withDefaultSchema() with the jdbcauthentication that you are using. As you have mentioned in that alternative that you may have to figure out way to use hashed password in that script.
Should you have any followup question, this baeldung blog post will help you.
https://www.baeldung.com/spring-security-jdbc-authentication
Hope this helps.

Using encrypted password for database connection in spring boot application through spring auto configuration

Trying to use encrypted database password to connect to database using spring auto configuration
I am using Spring auto configuration to connect to database. For that i added below properties in properties file:
spring.datasource.url=jdbc:oracle:thin:#ABCDE2D.com:1888:ABCDE2D1
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-oracle.jdbc.driver.OracleDriver
In my dao class, i have #Autowired NamedParameterJdbcTemplate and using it directly to get data from database.
Till here it is working fine.
Now i need to encrypt the password in properties file.
For that i did the below:
Added jasypt-spring-boot-starter in pom
Added spring.datasource.password=ENC(NoIv2c+WQYF3LenN0tDYPA==) in properties file
Added jasypt.encryptor.password=key in properties file
Now i am getting the below error:
Failed to bind properties under 'spring.datasource.password' to
java.lang.String:
Reason: Failed to bind properties under 'spring.datasource.password' to
java.lang.String
I'm providing some basic guide as follows.
You need to add following two parameters in to property file in order application to work properly. This is assuming you are encrypting using default encryption algorithm. If you are useing some other, then make sure to change it accordingly.
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndDES
You can refer to more details
https://nirmalbalasooriya.blogspot.com/2020/02/spring-boot-property-encryption-using.html
In my case I was giving wrong jasypt.encryptor.password.
For Example given below is properties I have set in my application.properties:
jasypt.encryptor.password=abc
instead abc I gave jasypt as my secret key while encrypting the password so the encripted password is wrong. Then it throwing this error.
Later I realised and found that the key is not correct.
Then gave the right key i.e., abc.Then it worked for me.
Silly mistake but it cost me 4 hours. Hope it will be useful for others.
If you are using jasypt dependency, make sure that:
spring.datasource.password = Enc
and
jasypt.encryptor.password = key
where Enc is encrypted password and key is the key which you used to generate the encrypted password.

Hide passwords in application properties of Spring boot application

Whenever the question of hiding the fields like passwords in application properties file arises,the straight-forward answer is encrypt those details using jasypt or other encryption.
If you keep encrypted passwords and jasypt details in same file, how does that make sense? or may be keep them in different file..
Any other smarter way for this?
You're not supposed to save the encryption key in application.properties, after all you don't want it going to your repository. You have to provide the key to your application when you run it, either by typing it or by storing it somewhere on your server. Check this thread for examples.
Let's assume that you have gotten your passwords in a typical application.properties file. Using Jaspyt, you may encrypt as follows:
Maven setup.... Grab the latest spring boot starter Jasypt POM, use
com.github.ulisesbocchio as the group ID.
Create a tiny utility class (preferably outside your spring boot app) to encrypt your passwords; it's easy to use Jasypt's BasicTextEncryptor class ex:
BasicTextEncryptor pwdEncrypt = new BasicTextEncryptor();
pwdEncrypt.setPassword(your_secret_sauce)//whatever you use here will be needed in the properties file (more on that later)
String encoded = pwdEncrypt.encrypt(password_you_want_to_encrpyt);
The String encoded is PBE-encoded by default; grab that
In your properties file, make the following entries:
jasypt.encryptor.password=your_secret_sauce //used in your utility
password_entry_you_want_to_encrypt=ENC(encoded) //encoded grabbed from your utility class
I'll assume that you're annotating your main class with
#SpringBootApplication. Add the following annotations as well:
#EnableEncryptableProperties
#PropertySource(name="EncryptedProperties", value = "classpath:application.properties")
Use jasypt to encrypt properties in application.properties file.
it's usesPBEWithMD5AndDES for the encryption.
See:
https://github.com/ulisesbocchio/jasypt-spring-boot

jasypt encryption not working in spring boot

I want to do encryption for some sensitive data in application.properties file of spring boot application.
for that I have used jasypt-spring-boot-starter plugin .
also used #EnableEncryptableProperties tag on spring application.
I have encrypted access key for my database and written its encrypted value in the property file.
com.test.SharedAccessKey=ENC(vfQQ9veC1G+RV8BC0VA==)
also provided in property file
jasypt.encryptor.password=secretpassword
jasypt.encryptor.algorithm=PBEWithMD5AndDES
I am accessing this property in spring boot application as followes
#Value("${com.test.SharedAccessKey}")
public String shareAcessKey;
But logger.info(shareAcessKey) print as it is ENC(vfQQ9veC1G+RV8BC0VA==)
what I am missing in above , can anyone help.
Issue was resolved . I have done some configuration in my spring Configuration class #Configuration related to property file.
as set property place holder configure to setIgnoreUnresolvablePlaceholders
after removing above code . Jasypt password is got picked up.

Spring Security 4 sessionRegistry doesn't populate Principal list

I am trying to implement a function where a admin user can terminate another user's session. I followed the official Spring Security documentation here: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#list-authenticated-principals and started with getting all currently logged in users through sessionRegistry.getAllPrincipals(), but it always returned an empty list.
I set a breakpoint in SessionRegistryImpl.registerNewSession() and could see it did indeed get invoked and it did add the UserDetails (my own implementation with both equals() and hashCode() implemented) to the hashmap principals. But when I access sessionRegistry bean from a Spring MVC controller, the list is always empty.
My configuration looks pretty much the same as the documentation.
How to fix this? Did anyone successfully get SessionRegistry to work with Spring Security 4? I remember I made it work with Spring Security 3 by following these intructions(enter link description here)
OK, so I fixed the issue by cleaning up the Spring configuration files, as suggested by the comments. Someone messed up with the web.xml - he added a reference to the context XML that is already referenced by the Spring's DispatcherServlet, causing it to be loaded twice. He didn't know it, because Spring references the file implicitly.
P.S.
I learned my lessons, but 2 things the Spring folks could do better (maybe in Spring 5?):
There shouldn't be implicit context file loading. Currently, the framework will try to load the application context from a file named [servlet-name]-servlet.xml located in the application's WebContent/WEB-INF directory. Convention over configuration fails in this case.
There should be warning when a bean is loaded twice, if someone need to override a bean definition, he must declare explicitly. Otherwise it would take a lot of time to debug the kind of error this mistake will cause.

Resources