Spring Boot shiro 去除Redis缓存
程序开发
2023-09-07 09:28:36
Spring Boot + shiro 去除Redis缓存
记录一些开发日常
之前的项目shiro都是和Redis整合在一起的,直到甲方要求项目部署到国产服务器上,国产服务器不支持Redis怎么办,只能改喽。
网上搜一下,修改方案千奇百怪,自己动手丰衣足食!
第一步:修改ShiroConfig
这一步就是把redis实现的缓存,改用session
修改前:
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;/*** @description:shiro配置*/
@Configuration
@Data
public class ShiroConfig {@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port}")private int port;@Value("${spring.redis.password:}")private String password;@Value("${shiro.timeout}")private int timeout;/*** Filter工厂,设置对应的过滤条件和跳转条件* @return ShiroFilterFactoryBean*/@Beanpublic ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);Map filters = new HashMap<>();filters.put("authc",new MyShiroAuthFilter());shiroFilterFactoryBean.setFilters(filters);// 过滤器链定义映射Map filterChainDefinitionMap = new LinkedHashMap<>();/** anon:可以匿名访问的url,* authc:认证通过才可以访问的url;* 过滤链定义,从上向下顺序执行,authc 应放在 anon 下面* */filterChainDefinitionMap.put("/login/login", "anon");filterChainDefinitionMap.put("/queryController/downloadZip", "anon");// 配置不会被拦截的链接 顺序判断filterChainDefinitionMap.put("/css/**", "anon");filterChainDefinitionMap.put("/fonts/**", "anon");filterChainDefinitionMap.put("/img/**", "anon");filterChainDefinitionMap.put("/js/**", "anon");filterChainDefinitionMap.put("/html/**", "anon");filterChainDefinitionMap.put("/file/**", "anon");filterChainDefinitionMap.put("/images/**", "anon");/*****************************swagger***************************/filterChainDefinitionMap.put("/swagger-ui.html", "anon");filterChainDefinitionMap.put("/webjars/**", "anon");filterChainDefinitionMap.put("/v2/**", "anon");filterChainDefinitionMap.put("/swagger-resources/**", "anon");/***************************************************************/// 认证通过才可以访问的urlfilterChainDefinitionMap.put("/**", "authc");//前后端分离中登录累面跳转应由前端路由控制,后台仅返回json数据, 对应LoginController中unauth请求,// 未登录已经在MyShiroAuthFilter的onAccessDenied进行拦截,为了防止拦截失效所以在这再做一次判断,通常不会执行这步代码。shiroFilterFactoryBean.setLoginUrl("/login/un_auth");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}/*** 凭证匹配器(由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了)* @return HashedCredentialsMatcher*/@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();// 散列算法:这里使用MD5算法;hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列的次数,比如散列两次,相当于 md5(md5(""));hashedCredentialsMatcher.setHashIterations(PassWordInitConfig.MD5_COUNT);return hashedCredentialsMatcher;}/*** 将自己的验证方式加入容器* @return MyShiroRealm*/@Beanpublic MyShiroRealm myShiroRealm() {MyShiroRealm myShiroRealm = new MyShiroRealm();myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());return myShiroRealm;}/*** RedisSessionDAO shiro sessionDao层的实现 通过redis, 使用的是shiro-redis开源插件* @return RedisSessionDAO*/@Beanpublic RedisSessionDAO redisSessionDAO() {RedisSessionDAO redisSessionDAO = new RedisSessionDAO();redisSessionDAO.setRedisManager(redisManager());redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());redisSessionDAO.setExpire(timeout*60);return redisSessionDAO;}/*** Session ID 生成器* @return JavaUuidSessionIdGenerator*/@Beanpublic JavaUuidSessionIdGenerator sessionIdGenerator() {return new JavaUuidSessionIdGenerator();}/*** 自定义sessionManager* @return SessionManager*/@Beanpublic SessionManager sessionManager() {MySessionManager mySessionManager = new MySessionManager();mySessionManager.setSessionDAO(redisSessionDAO());return mySessionManager;}/*** 配置shiro redisManager, 使用的是shiro-redis开源插件* @return RedisManager*/private RedisManager redisManager() {RedisManager redisManager = new RedisManager();redisManager.setHost(host+":"+port);if (StringUtils.isNotBlank(password)) {redisManager.setPassword(password);}return redisManager;}/*** cacheManager 缓存 redis实现, 使用的是shiro-redis开源插件* @return RedisCacheManager*/@Beanpublic RedisCacheManager cacheManager() {RedisCacheManager redisCacheManager = new RedisCacheManager();redisCacheManager.setRedisManager(redisManager());// 必须要设置主键名称,shiro-redis 插件用过这个缓存用户信息redisCacheManager.setPrincipalIdFieldName("userAccount");return redisCacheManager;}/*** description: 权限管理,配置主要是Realm的管理认证* @return SecurityManager*/@Beanpublic SecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(myShiroRealm());// 自定义session管理 使用redissecurityManager.setSessionManager(sessionManager());// 自定义缓存实现 使用redissecurityManager.setCacheManager(cacheManager());return securityManager;}/*** 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证* 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能*/@Beanpublic DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}
}
修改后:
import lombok.Data;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;/*** @description:shiro配置*/
@Configuration
@Data
public class ShiroConfig {/*** Filter工厂,设置对应的过滤条件和跳转条件* @return ShiroFilterFactoryBean*/@Beanpublic ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);Map filters = new HashMap<>();filters.put("authc",new MyShiroAuthFilter());shiroFilterFactoryBean.setFilters(filters);// 过滤器链定义映射Map filterChainDefinitionMap = new LinkedHashMap<>();/** anon:可以匿名访问的url,* authc:认证通过才可以访问的url;* 过滤链定义,从上向下顺序执行,authc 应放在 anon 下面* */filterChainDefinitionMap.put("/login/login", "anon");filterChainDefinitionMap.put("/queryController/downloadZip", "anon");// 配置不会被拦截的链接 顺序判断filterChainDefinitionMap.put("/css/**", "anon");filterChainDefinitionMap.put("/fonts/**", "anon");filterChainDefinitionMap.put("/img/**", "anon");filterChainDefinitionMap.put("/js/**", "anon");filterChainDefinitionMap.put("/html/**", "anon");filterChainDefinitionMap.put("/file/**", "anon");filterChainDefinitionMap.put("/images/**", "anon");/*****************************swagger***************************/filterChainDefinitionMap.put("/swagger-ui.html", "anon");filterChainDefinitionMap.put("/webjars/**", "anon");filterChainDefinitionMap.put("/v2/**", "anon");filterChainDefinitionMap.put("/swagger-resources/**", "anon");/***************************************************************/// 认证通过才可以访问的urlfilterChainDefinitionMap.put("/**", "authc");//前后端分离中登录累面跳转应由前端路由控制,后台仅返回json数据, 对应LoginController中unauth请求,// 未登录已经在MyShiroAuthFilter的onAccessDenied进行拦截,为了防止拦截失效所以在这再做一次判断,通常不会执行这步代码。shiroFilterFactoryBean.setLoginUrl("/login/un_auth");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}/*** 凭证匹配器(由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了)* @return HashedCredentialsMatcher*/@Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();// 散列算法:这里使用MD5算法;hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列的次数,比如散列两次,相当于 md5(md5(""));hashedCredentialsMatcher.setHashIterations(PassWordInitConfig.MD5_COUNT);return hashedCredentialsMatcher;}/*** 将自己的验证方式加入容器* @return MyShiroRealm*/@Beanpublic MyShiroRealm myShiroRealm() {MyShiroRealm myShiroRealm = new MyShiroRealm();myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());return myShiroRealm;}@Beanpublic DefaultSecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 设置realm.securityManager.setRealm(myShiroRealm());//设置缓存securityManager.setCacheManager(getCacheManager());securityManager.setSessionManager(sessionManager());return securityManager;}/**** 缓存框架* @return*/@Beanpublic EhCacheManager getCacheManager(){EhCacheManager ehCacheManager = new EhCacheManager();ehCacheManager.setCacheManagerConfigFile("classpath:shiro-ehcache.xml");return ehCacheManager;}/*** 自定义sessionManager* @return SessionManager*/@Beanpublic SessionManager sessionManager() {MySessionManager mySessionManager = new MySessionManager();return mySessionManager;}/*** 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证* 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能*/@Beanpublic DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}
}
第二步:新增shiro-ehcache.xml
在上一步可以看到,增加了一个EhCacheManager 的缓存框架,里面有一个配置文件classpath:shiro-ehcache.xml,这文件创建在哪呢,没错就是resource下
第三步:注释pom引入的Redis依赖
这一步就不用多说了,搜索redis关键字注释依赖,然后clean一下,启动项目看看是否正常
标签:
上一篇:
HTML5新控件 - 进度条progress
下一篇:
相关文章
-
无相关信息