I also want to be more specific about my problem.
I figured out that by using the StandardPasswordEncoder, I could use it once to create the salt, and then use it a second time to create a hashed password using the salt as a the "secret" constructor parameter.
Maybe this overkill, but this is generally how I wanted to salt the passwords all along. At least it works and I know stuff is secure.
Anyway, now I have my UserAccount object with 3 methods of interest:
- generateSalt()
- generateHashedPassword()
- matchesPassword()
These methods use the StandardPasswordEncoder class
Now, I'd like to use these in an authentication provider, but I realized that the default one only takes a UserDetails interface... which is how I was doing it before. I should have looked to see how Spring Security wanted me to do this.
Which is better:
1. Should I rip out the default Authentication Provider and use my UserAccount matchesPassword() method? Assuming I do this approach, is this all I need?:
Code:
@Component(value = "authenticationProvider")
public class AuthenticationProviderImpl extends AbstractUserDetailsAuthenticationProvider {
@Autowired
UserAccountManager userAccountManager;
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
return userAccountManager.loadUserByUsername(username);
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
UserAccount userAccount = (UserAccount) userDetails;
if(!userAccount.matchesPassword(authentication.getCredentials().toString())) {
throw new BadCredentialsException("The username or password is incorrect.");
}
}
}
2. Should I abandon my 3 methods and use an alternate approach that Spring Security provides out of the box in its default Authentication Manager? Is that as secure as my approach?
Thanks