这篇文章是对上一篇 34 | Spring Boot整合Shiro框架(Shiro简介+实现登录拦截、用户认证、请求授权并整合Mybatis和Thymeleaf)的扩展
当两个用户的密码相同时,单纯使用不加盐的MD5加密方式,会发现数据库中存在相同结构的密码,这样是不安全的。为了实现两个人的原始密码一样,但加密后的结果是不一样的效果,就要使用加了盐的MD5加密方式。其实就好像炒菜一样,两道一样的鱼香肉丝,加的盐不一样,炒出来的味道就不一样。
即创建HashedCredentialsMatcher对象,并设置加密算法即可 注意: 如果你没有配置此类,你会发现尽管密码被加密,但你输入原始密码是等不进去的,因为这个HashedCredentialsMatcher类处理密码校验
package com.nsx.shiro.config; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; /** * Created by NXS * 2020/9/1 17:05 */ @Configuration public class ShiroConfig { //shiroFilterFactoryBean 3 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // 设置安全管理器 factoryBean.setSecurityManager(securityManager); /* anon:无需认证就可以访问 authc:必须认证了才能访问 user:必须拥有 记住我功能才能用 perms:拥有对某个资源的权限才能访问 role:拥有某个角色权限才能访问 */ //添加shiro的内置过滤器 拦截 Map<String, String> fiterMap = new LinkedHashMap<>(); // 设置哪些路径授予哪些权限 fiterMap.put("/user/add", "perms[user:add]"); fiterMap.put("/user/update", "perms[user:update]"); // /user/* 指的是路径 必须认证了才能访问 fiterMap.put("/user/*", "authc"); factoryBean.setFilterChainDefinitionMap(fiterMap); // 设置登录的请求 factoryBean.setLoginUrl("/toLogin"); // 跳转至未授权页面 factoryBean.setUnauthorizedUrl("/unauthorize"); return factoryBean; } //DefaultWebSecurityManager 2 @Bean(name = "securityManager") public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 关联userRealm securityManager.setRealm(userRealm); return securityManager; } //创建realm对象,需要自定义类 1 @Bean public UserRealm userRealm(@Qualifier("credentialsMatcher") HashedCredentialsMatcher matcher) { UserRealm userRealm = new UserRealm(); userRealm.setCredentialsMatcher(matcher); return userRealm; } // ShiroDialect 用来整合shiro和thymleaf @Bean public ShiroDialect getShiroDialect() { return new ShiroDialect(); } /** * 替换当前 Realm 的 credentialsMatcher 属性. * 直接使用 HashedCredentialsMatcher 对象, 并设置加密算法即可. * 密码校验规则HashedCredentialsMatcher * 这个类是为了对密码进行编码的 * 防止密码在数据库中明码表示,当然在登录认证的时候, * 这个类也负责对form里输入的密码进行编码 * 处理认证匹配处理器 */ @Bean("credentialsMatcher") public HashedCredentialsMatcher credentialsMatcher() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //设置加密算法 matcher.setHashAlgorithmName("MD5"); //设置加密次数 matcher.setHashIterations(1000); //是否存储为16进制 //将setStoredCredentialsHexEncoded设置为true,则需要使用toHex()进行转换成字符串,默认使用的是toBase64() matcher.setStoredCredentialsHexEncoded(true); return matcher; } }重点加入什么,参见下面图片
分享视频啦啦啦啦啦啦
最后总结一下Shiro的MD5加盐加密: 1)在doGetAuthenticationInfo方法返回值创建SimpleAuthenticationInfo对象的时候,需要使用 SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName)构造器。 2)使用ByteSource.Util.bytes()来计算盐值 3)盐值需要唯一,一般使用随机字符串或者userid 4)使用new SimpleHash(hashAlgorithmName,crdentials,salt,hashIterations)来进行MD5盐值加密,并且hashIterations一定要与HashedCredentialsMatcher设置的加密次数相同 参考:http://blog.csdn.net/acmman/article/details/78585662