這是我第二次在項目中使用apache shiro
,但第一次是salting
密碼。這是我使用apache shiro 1.2.0
的時間。我在使用jsp,spring,JPA(spring-data-jpa)的web應用程序中使用shiro,並在保存到數據庫之前使用SHA256
進行加密,然後使用base64
。我有一個SaltedJPARealm
,一個Sha256CredentialMatcher
它實現了一個HashedCredentialMatcher。這就是我要做的麻煩apache shiro saltedauthentication.hashProvidedCredentials沒有給出預期的散列
在我的控制器創建用戶
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());
所以應該我的密碼是password1234
和生成的鹽是所以在我的數據庫,我有密碼:whb+0AihIGJ4n8QwULj1tR6qSwCrA+1BUvnoe4q4Cy4=
鹽在salt field in the database
是一樣的。
在我在春天的配置是:
<!--....-->
<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>
<!--....-->
登錄用戶
Subject currentUser = SecurityUtils.getSubject();
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken(loginForm.getEmail(), loginForm.getPassword(), loginForm.isRememberMe());
SecurityUtils.getSubject().login(token);
}
的SaltedJPARealm's doGetAuthenticationInfo(AuthenticationToken at)
回報SaltedAuthenticationInfo
從數據庫中獲取用戶後:
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
return new SimpleAuthenticationInfo(user, user.getPassword().toCharArray(),salt,this.getName());
的Sha256CredentialMatcher的32051106540樣子:
Object tokenfromSubmition = hashProvidedCredentials(token.getCredentials(),((SaltedAuthenticationInfo)info).getCredentialsSalt(),0);
Object passwordFromStorage =this.getCredentials(info);
Boolean match = equals(tokenfromSubmition, passwordFromStorage);
return match;
完整的代碼可here on pastie認證失敗與此有關。但是當我更改密碼時不要使用密碼(創建帳戶時)並返回AuthenticationInfo而不是SaltedAuthenticationInfo。它適用於同一班級。我在想,究竟做錯了什麼?
是否有你沒有使用PasswordMatcher和PasswordService的原因?這些自動使用安全隨機生成的鹽,並直接進行密碼比較。 –
'passwordService'使用默認的'sha-256'加密和50,000次迭代(我認爲是這樣),我還沒有找到任何方法來改變這些默認值。在嘗試時,在生成密碼時調試過程中似乎很慢。所以我回落到自定義實現。謝謝 –
我在下面回答了有關'passwordService'用法的問題。我知道它沒有解決你最初發布的問題,但我認爲你會發現使用起來更容易/更好。 –