问题
I would like to add salt like:
PasswordEncoder encoder = new ShaPasswordEncoder();
userDetails.setPassword(encoder.encodePassword(userDetails.getPassword(),saltSource.getSalt(userDetails));
as far userDetails
is instance of my custom UserDetail
class,i obliged to cast it to this spring class:UserDetails
,but as it's logically expected i got in Runtime:
java.lang.ClassCastException: model.UserDetails cannot be cast to org.springframework.security.core.userdetails.UserDetails
config:
<beans:bean id="saultSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="username"/>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder hash="sha">
<salt-source user-property="username"/>
</password-encoder>
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
</authentication-manager>
How can I configure salt correctly in this case?
回答1:
ReflectionSaltSource
only works with a UserDetails
object (I'm assuming that's where you get the class-cast exception?), so you would have to either implement UserDetails
or create your own SaltSource
implementation which works with your object.
However, I wouldn't use a property of the user as the salt unless you are working with a legacy system which already does this. The username is not a very good salt value. It's much better to use a random salt which is stored with the password. A good example is the BCrypt algorithm. See my answer to this question for an example of using it with Spring Security 3.1. As explained there, BCrypt automatically generates a random salt which it stores in the same string as the hashed password.
Note that there is actually a new PasswordEncoder interface in the Spring Security 3.1 "crypto" package (in org.springframework.security.crypto.password
). This doesn't include a salt in the API methods, since it assumes the salt is internally generated (as it is with the BCrypt implementation). The framework will generally accept one of these or the legacy org.springframework.security.authentication.encoding.PasswordEncoder
.
回答2:
Your model.UserDetails
class must implement the interface org.springframework.security.core.userdetails.UserDetails
- it does not need to be a class org.springframework.security.core.userdetails.User
.
You can also have a look at this answer to see how to set up a ReflectionSaltSource
for both encoding and decoding passwords, or help You get the bigger picture to follow Luke's great tip on BCryptPasswordEncoder
.
回答3:
I've written a blog post about some of these details here: http://rtimothy.tumblr.com/post/26527448708/spring-3-1-security-and-salting-passwords Luke wrote the code so he certainly knows what he's talking about, but I see a number of people including myself having a hard time groking this information, hopefully that like will help.
来源:https://stackoverflow.com/questions/8658584/spring-security-salt-for-custom-userdetails