Shiro 认证失败
Shiro Authentication failed
我在 JSF2+Hibernate 项目中使用 shiro 1.2.3。没有运气让用户通过身份验证。无法弄清楚我做错了什么。
shiro.ini
[main]
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager
hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = 100000
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordService.hashService = $hashService
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
customSecurityRealm = com.sapienzo.common.CustomSecurityRealm
customSecurityRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $customSecurityRealm
ShiroUtils class(帮助程序 class 创建加盐哈希)
public class ShiroUtils {
private static int HASH_ITERATIONS = 100000;
public static String createSaltedHash(String plainTextPassword) {
DefaultHashService hashService = new DefaultHashService();
hashService.setHashIterations(HASH_ITERATIONS);
hashService.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
hashService.setGeneratePublicSalt(true);
DefaultPasswordService passwordService = new DefaultPasswordService();
passwordService.setHashService(hashService);
String encryptedPassword = passwordService.encryptPassword(plainTextPassword);
return encryptedPassword;
}
}
注册时将用户保存到数据库(从表单字段获取用户名和密码)
...
user.setUsername(username);
user.setPassword(ShiroUtils.createSaltedHash(password);
userService.saveUser(user);
...
登录(同样来自表单字段的用户名和密码)
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), ShiroUtils.createSaltedHash(user.getPassword()));
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);
CustomSecurityRealm.java
public class CustomSecurityRealm extends AuthorizingRealm {
public CustomSecurityRealm() {
setName("CustomSecurityRealm");
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
if (token.getUsername() == null) {
return null;
}
UserService userService = new UserService();
String saltedHashPassword = userService.getPasswordByUsername(token.getUsername()); //get encrypted password from DB
if( saltedHashPassword != null ) {
SimpleAuthenticationInfo authn = new SimpleAuthenticationInfo(token.getUsername(), saltedHashPassword, getName());
return authn;
} else {
return null;
}
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
逐行挖掘代码后,我注意到 passwordsMatch
用于密码比较的方法总是 returns false 无论输入如何.
例如:
String plainTextPassword = "foo";
DefaultPasswordService passwordService = new DefaultPasswordService();
String encryptedPassword = passwordService.encryptPassword(plainTextPassword);
boolean result = passwordService.passwordsMatch(plainTextPassword, encryptedPassword);
System.out.println(result);
输出为 false。后来发现this post。导致这是一个报告的错误。如果您的默认语言环境与 English 不同,shiro 在(取消)大写字母时会感到困惑。您应该将默认语言环境设置为 Locale.ENGLISH
以解决此问题。
我在 JSF2+Hibernate 项目中使用 shiro 1.2.3。没有运气让用户通过身份验证。无法弄清楚我做错了什么。
shiro.ini
[main]
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager
hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = 100000
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordService.hashService = $hashService
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
customSecurityRealm = com.sapienzo.common.CustomSecurityRealm
customSecurityRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $customSecurityRealm
ShiroUtils class(帮助程序 class 创建加盐哈希)
public class ShiroUtils {
private static int HASH_ITERATIONS = 100000;
public static String createSaltedHash(String plainTextPassword) {
DefaultHashService hashService = new DefaultHashService();
hashService.setHashIterations(HASH_ITERATIONS);
hashService.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
hashService.setGeneratePublicSalt(true);
DefaultPasswordService passwordService = new DefaultPasswordService();
passwordService.setHashService(hashService);
String encryptedPassword = passwordService.encryptPassword(plainTextPassword);
return encryptedPassword;
}
}
注册时将用户保存到数据库(从表单字段获取用户名和密码)
...
user.setUsername(username);
user.setPassword(ShiroUtils.createSaltedHash(password);
userService.saveUser(user);
...
登录(同样来自表单字段的用户名和密码)
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), ShiroUtils.createSaltedHash(user.getPassword()));
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);
CustomSecurityRealm.java
public class CustomSecurityRealm extends AuthorizingRealm {
public CustomSecurityRealm() {
setName("CustomSecurityRealm");
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
if (token.getUsername() == null) {
return null;
}
UserService userService = new UserService();
String saltedHashPassword = userService.getPasswordByUsername(token.getUsername()); //get encrypted password from DB
if( saltedHashPassword != null ) {
SimpleAuthenticationInfo authn = new SimpleAuthenticationInfo(token.getUsername(), saltedHashPassword, getName());
return authn;
} else {
return null;
}
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
逐行挖掘代码后,我注意到 passwordsMatch
用于密码比较的方法总是 returns false 无论输入如何.
例如:
String plainTextPassword = "foo";
DefaultPasswordService passwordService = new DefaultPasswordService();
String encryptedPassword = passwordService.encryptPassword(plainTextPassword);
boolean result = passwordService.passwordsMatch(plainTextPassword, encryptedPassword);
System.out.println(result);
输出为 false。后来发现this post。导致这是一个报告的错误。如果您的默认语言环境与 English 不同,shiro 在(取消)大写字母时会感到困惑。您应该将默认语言环境设置为 Locale.ENGLISH
以解决此问题。