首先记录一下生成盐的工具类。
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
/**
* @Author WPF
* @Description TODO
* @Created 2019/8/18 22:34
*/
public class SecurityUtil {
//随机数生成器
private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
//指定散列算法为md5
private static String algorithmName = "MD5";
//散列迭代次数
private final static int hashIterations = 2;
/**
* 获取密码获取加密后的密码(盐值随机)
* @return
*/
public static String getPassword(String password){
String salt = randomNumberGenerator.nextBytes().toHex();
return getPassword(password,salt);
}
/**
* 获取随机盐值
* @return
*/
public static String getSalt(){
return randomNumberGenerator.nextBytes().toHex();
}
/**
* 根据密码和盐值 获取加密后的密码
* @return
*/
public static String getPassword(String password,String salt){
String newPassword = new SimpleHash(algorithmName,password,
ByteSource.Util.bytes(salt),hashIterations).toHex();
return newPassword;
}
}
自定义userReaml的doGetAuthenticationInfo()验证登录的方法中加上
//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
shiroUser,
user.getPassword(),
ByteSource.Util.bytes(user.getSalt()), //salt=username+salt,采用明文访问时,不需要此句
getName()
);
shiro的配置类
/**
* Shiro Realm 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的
*/
@Bean
public UserRealm userRealm() {
UserRealm userRealm = new UserRealm();
userRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return userRealm;
}
/**
* 凭证匹配器
* (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
* 所以我们需要修改下doGetAuthenticationInfo中的代码;
* )
* 可以扩展凭证匹配器,实现 输入密码错误次数后锁定等功能,下一次
*/
@Bean(name = "credentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashAlgorithmName("md5");
//散列的次数,比如散列两次,相当于 md5(md5(""));
hashedCredentialsMatcher.setHashIterations(2);
//storedCredentialsHexEncoded默认是true,此时用的是密码加密用的是Hex编码;false时用Base64编码
hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
return hashedCredentialsMatcher;
}