Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security Salt

Tags:

I'm trying to add a salt when adding a new user/pwd, but the docs seem to be missing how to do this.

Here's a basic example:

<authentication-manager>     <authentication-provider user-service-ref="userDetailsService">         <password-encoder hash="md5">             <salt-source user-property="username"/>         </password-encoder>     </authentication-provider> </authentication-manager> 

You can see by the example that neither a custom salt or custom password encoder is used.

So, how would I wire the Salt in when adding a new user/pwd? I'd assume it would be something along the lines of:

@Autowired SaltSource saltSource; protected void foo(final CustomUser user) {     final PasswordEncoder encoder = new Md5PasswordEncoder();     user.setPassword(encoder.encodePassword(user.getPassword(), saltSource)); } 

However, since I am using the default salt/password encoders and I don't have a custom salt bean the autowire would fail.

Any clue how to make this work?

like image 388
user973479 Avatar asked Nov 09 '11 15:11

user973479


People also ask

What is salt in Spring Security?

A salt is a sequence of randomly generated bytes that is hashed along with the password. The salt is stored in the storage and doesn't need to be protected. Whenever the user tries to authenticate, the user's password is hashed with the saved salt and the result should match the stored password.

How should passwords be stored in spring?

Instead of using just the password as input to the hash function, random bytes (known as salt) would be generated for every users' password. The salt and the user's password would be ran through the hash function which produced a unique hash. The salt would be stored alongside the user's password in clear text.

How does Spring Security know password?

To verify the user entered the correct password, use the same one way hash against their entered value and then compare it with the previously hashed value - if they are the same, then the entered password is correct.

What is the use of BCryptPasswordEncoder?

Class BCryptPasswordEncoderImplementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom instance. The larger the strength parameter the more work will have to be done (exponentially) to hash the passwords.


1 Answers

You don't autowire the SaltSource when adding user. The SaltSource is an abstraction used by Spring to provide the source of the salt for password checking only.

To create a properly encoded password hash You just past the salt itself to the PasswordEncoder - the value of username property, not the SaltSource:

private PasswordEncoder encoder = new Md5PasswordEncoder();  public User createUser(String username, String plainTextPassword) {     User u = new User();     u.setUsername(username);     u.setPassword(encoder.encodePassword(plainTextPassword, username));     getEntityManager().persist(u); // optional     return u; } 

Moreover the autowire of SaltSource won't work until it's defined as an inner bean. You could define the ReflectionSaltSource as top level bean and pass it's ID to the password-encoder, i.e.:

<bean id="saltSource"     class="org.springframework.security.authentication.dao.ReflectionSaltSource"     p:userPropertyToUse="username" />  <bean id="passwordEncoder"      class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />  <bean id="daoAuthenticationProvider"     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"     p:passwordEncoder-ref="passwordEncoder"     p:saltSource-ref="saltSource"     p:userDetailsService-ref="userDetailsService" />  <authentication-manager>     <authentication-provider ref="daoAuthenticationProvider" /> </authentication-manager> 

And then:

@Autowired private PasswordEncoder passwordEncoder; @Autowired private SaltSource saltSource;  public CustomUserDetails createUser(String username, String plainTextPassword) {     CustomUserDetails u = new CustomUserDetails();     u.setUsername(username);     u.setPassword(passwordEncoder.encodePassword(             plainTextPassword, saltSource.getSalt(u)));     getEntityNamager().persist(u); // optional     return u; }  
like image 173
Roadrunner Avatar answered Sep 19 '22 16:09

Roadrunner