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?
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;
}