首先记录一下生成盐的工具类。
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();//指定散列算法为md5private 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验证用户登录的类为自定义的*/@Beanpublic 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;}