shiro登录验证一直失败:
原因:
在用户注册时,采用如下加密方法:
/**
* md5加密工具
* @param var
* 要加密的字符串
* @param iterations
* 加密次数
* @return
*/
public static String encrypt(String var,int iterations){
return new SimpleHash("md5",var,SALT.getBytes(),iterations).toHex();
}
在ShiroConfig中:
@Bean
public ShiroRealm shiroRealm() {
ShiroRealm shiroRealm = new ShiroRealm();
return shiroRealm;
}
/**
* 加密
*
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法
hashedCredentialsMatcher.setHashIterations(2);//散列的次数
return hashedCredentialsMatcher;
}
因为注册时存入数据库的是经过两次MD5加密的,但是在ShiroRealm中却未指定加密方法,导致UserPasswordToken是以明文存在的,所以需要在shiroRealm()中加上:
//设置加密方式
shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
同时必须保持入库时的加密方法和Shiro登录验证时的加密方法一致,包括加密次数、盐值也要一致。
修改hashedCredentialsMatcher()如下:
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法
hashedCredentialsMatcher.setHashIterations(2);//散列的次数
hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);//转化为16进制(与入库时保持一致)
return hashedCredentialsMatcher;
}
(注意:我这里采用固定盐值,实际上应该不同用户不同盐值,一般为用户id+固定字符串,盐值略)
总结:
在使用Shiro进行认证时,加密规则要和数据入库时保持一致,包括加密规则,加密次数,盐值,都要一致。