问题
This is the second time I'm using apache shiro
in a project but the first time am salting
the password.this time around i use apache shiro 1.2.0
. I'm using shiro in a web application using jsp, spring, JPA(spring-data-jpa) and using SHA256
for encryption then base64
before saving to database. I have a SaltedJPARealm
, a Sha256CredentialMatcher
which implements a HashedCredentialMatcher. this is how i do
creating a user in my controller
RandomNumberGenerator rng = new SecureRandomNumberGenerator();
ByteSource salt = rng.nextBytes(10);
String hashedPasswordBase64 = new Sha256Hash(signupForm.getPassword(),salt).toBase64();
userService.createUser(signupForm.getFullName(), signupForm.getEmail(), hashedPasswordBase64, salt.toBase64());
so supposed my password is password1234
and the generated salt is /ZFfGOcSxYhy+g==
so in my database i have password: whb+0AihIGJ4n8QwULj1tR6qSwCrA+1BUvnoe4q4Cy4=
the salt in the salt field in the database
is the same.
In my configuration in spring is:
<!--....-->
<bean id="saltedJPARealm" class="bla.bla.webapp.security.SaltedJPARealm">
<constructor-arg ref="credMatcher"/>
</bean>
<bean id="credMatcher" class="bla.bla.webapp.security.Sha256CredentialMatcher">
<property name="storedCredentialsHexEncoded" value="false" />
<property name="hashAlgorithmName" value="SHA-256" />
<!--<property name="hashIterations" value="1024" />-->
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" depends-on="userRepository">
<property name="realm" ref="saltedJPARealm" />
</bean>
<!--....-->
login user
Subject currentUser = SecurityUtils.getSubject();
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken(loginForm.getEmail(), loginForm.getPassword(), loginForm.isRememberMe());
SecurityUtils.getSubject().login(token);
}
The SaltedJPARealm's doGetAuthenticationInfo(AuthenticationToken at)
returns SaltedAuthenticationInfo
after getting the user from the database :
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
return new SimpleAuthenticationInfo(user, user.getPassword().toCharArray(),salt,this.getName());
the doCredentialsMatch
of Sha256CredentialMatcher looks like :
Object tokenfromSubmition = hashProvidedCredentials(token.getCredentials(),((SaltedAuthenticationInfo)info).getCredentialsSalt(),0);
Object passwordFromStorage =this.getCredentials(info);
Boolean match = equals(tokenfromSubmition, passwordFromStorage);
return match;
full code is available here on pastie the authentication fails with this. but when i change the code not to salt the password(when creating account) and return AuthenticationInfo as opposed to SaltedAuthenticationInfo. it works with the same class. am wondering what exactly am doing wrong?
回答1:
The PasswordService
is a POJO (with nested properties) and its nested properties can be configured just as well with Spring:
<bean id="passwordService" class="org.apache.shiro.authc.credential.DefaultPasswordService">
<property name="hashService.hashAlgorithmName" value="SHA-512"/>
<property name="hashService.hashIterations" value="500000"/>
</bean>
<bean id="myRealm" class="...">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.PasswordMatcher">
<property name="passwordService" ref="passwordService"/>
</bean>
</property>
</bean>
This allows the myRealm
instance to use the PasswordService for credentials checking during a login attempt.
To use the PasswordService to encrypt passwords when the end user sets their password (i.e. during account registration or password reset), you can inject the PasswordService
bean and then use it:
String encryptedPassword = passwordService.encryptPassword(signupForm.getPassword());
userService.createUser(signupForm.getFullName(), signupForm.getEmail(), encryptedPassword);
I think you'll find the Spring config and code usage much nicer/cleaner to use than the lower-level random number generators and HashService + Hash APIs.
HTH!
来源:https://stackoverflow.com/questions/12896592/having-trouble-with-apache-shiro-saltedauthentication-hashprovidedcredentials-no