美文网首页springboot
SpringBoot集成Shiro+Redis实现session

SpringBoot集成Shiro+Redis实现session

作者: 蓝雄威 | 来源:发表于2018-12-31 13:55 被阅读224次

    一、前言

    当我们的用户量到达一定程度的时候,单机的服务器已经支撑不了目前的访问量,我们肯定需要对服务器做集群来提高应用的负载能力.比如我们使用Nginx+Tomcat来实现集群,如果使用的是轮询的测试,我肯定需要涉及到Session共享的问题,解决Session共享有很多种方案,我们选择的是Shiro+Redis来实现。因为Shiro中本身就提供了sessionManager和sessionDAO,我们可以把shiro和redis集成起来,把session持久化到Redis中,然后需要使用的时候从Redis中获取对应的session.

    二、实现步骤

    步骤一:

    在application.properties配置文件中添加Redis相关的配置

    #redis
    # Redis服务器地址
    redis.host= localhost
    # Redis服务器连接端口
    redis.port= 6379
    redis.jedis.pool.max-active=
    # 连接池中的最大空闲连接
    redis.pool.max-idle= 8
    # 连接池中的最小空闲连接
    redis.pool.min-idle= 0
    # 连接池最大连接数(使用负值表示没有限制)
    redis.pool.max-active= 8
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    redis.pool.max-wait= -1
    # 连接超时时间(毫秒)
    redis.timeout= 0
    redis.password=
    
    步骤二

    我们需要在pom.xml中添加Shiro集成Redis的依赖

    <dependency>
          <groupId>org.crazycake</groupId>
          <artifactId>shiro-redis</artifactId>
           <version>2.4.2.1-RELEASE</version>
          <exclusions>
                <exclusion>
                      <artifactId>shiro-core</artifactId>
                       <groupId>org.apache.shiro</groupId>
                </exclusion>
           </exclusions>
    </dependency>
    

    步骤三

    在Shiro相关配置中添加SessionManager和SessionDAO

    package cn.wolfcode.saas.pss.config.shiro;
    
    import cn.wolfcode.saas.pss.config.redis.RedisConfig;
    import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
    import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.apache.shiro.web.servlet.AbstractShiroFilter;
    import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
    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.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.annotation.PostConstruct;
    import javax.servlet.Filter;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * Created by wolfcode-lanxw
     */
    @Configuration
    public class ShiroConfig {
        /**
         * 配置shiro redisManager
         * 使用的是shiro-redis开源插件
         * @return
         */
        @Bean
        public RedisManager redisManager(RedisConfig redisConfig) {
            RedisManager redisManager = new RedisManager();
            redisManager.setHost(redisConfig.getHost());
            redisManager.setPort(redisConfig.getPort());
            redisManager.setExpire(1800);// 配置缓存过期时间
            redisManager.setTimeout(redisConfig.getTimeout());
            return redisManager;
        }
        @Bean
        public RedisSessionDAO redisSessionDAO(RedisManager redisManager) {
            RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
            redisSessionDAO.setRedisManager(redisManager);
            return redisSessionDAO;
        }
        /**
         * shiro session的管理
         */
        @Bean
        public DefaultWebSessionManager redisSessionManager(RedisSessionDAO redisSessionDAO) {
            DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
            sessionManager.setSessionDAO(redisSessionDAO);
            return sessionManager;
        }
        @Bean
        public RedisCacheManager redisCacheManager(RedisManager redisManager) {
            RedisCacheManager redisCacheManager = new RedisCacheManager();
            redisCacheManager.setRedisManager(redisManager);
            return redisCacheManager;
        }
        /*
        创建安全管理器对象,关联自定义Realm
         */
        @Bean
        public DefaultWebSecurityManager securityManager(UserRealm userRealm,DefaultWebSessionManager redisSessionManager,RedisCacheManager redisCacheManager){
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(userRealm);
            securityManager.setSessionManager(redisSessionManager);
            securityManager.setCacheManager(redisCacheManager);
            return securityManager;
        }
        @Bean(name = "shiroFilterFactoryBean")
        protected ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
    
            Map<String, Filter> filterMap = new LinkedHashMap<>();
            filterMap.put("authc", new AjaxPermissionsAuthorizationFilter());
            shiroFilterFactoryBean.setFilters(filterMap);
    
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
            filterChainDefinitionMap.put("/", "anon");
            filterChainDefinitionMap.put("/static/**", "anon");
            filterChainDefinitionMap.put("/error", "anon");
            filterChainDefinitionMap.put("/login", "anon");
            filterChainDefinitionMap.put("/**", "authc");
    
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
        }
        /**
         *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
         * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
         * @return
         */
        @Bean
        public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
            DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
            advisorAutoProxyCreator.setProxyTargetClass(true);
            return advisorAutoProxyCreator;
        }
    
        /**
         * 开启aop注解支持
         * @param securityManager
         * @return
         */
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    }
    

    主要是在DefaultWebSecurityManager中需要配置对应的sessionManager和CacheManager即可.
    配置好之后,当登录完成,会在Redis中看到对应的key.而且此时的缓存也交给了redis来处理了

    相关文章

      网友评论

        本文标题:SpringBoot集成Shiro+Redis实现session

        本文链接:https://www.haomeiwen.com/subject/hnwilqtx.html