SpringBoot集成Shiro+Redis實(shí)現(xiàn)session共享

一土陪、前言

當(dāng)我們的用戶量到達(dá)一定程度的時(shí)候箭窜,單機(jī)的服務(wù)器已經(jīng)支撐不了目前的訪問(wèn)量忍些,我們肯定需要對(duì)服務(wù)器做集群來(lái)提高應(yīng)用的負(fù)載能力.比如我們使用Nginx+Tomcat來(lái)實(shí)現(xiàn)集群,如果使用的是輪詢的測(cè)試撬统,我肯定需要涉及到Session共享的問(wèn)題,解決Session共享有很多種方案,我們選擇的是Shiro+Redis來(lái)實(shí)現(xiàn)缝呕。因?yàn)镾hiro中本身就提供了sessionManager和sessionDAO,我們可以把shiro和redis集成起來(lái)皂甘,把session持久化到Redis中玻驻,然后需要使用的時(shí)候從Redis中獲取對(duì)應(yīng)的session.

二、實(shí)現(xiàn)步驟

步驟一:

在application.properties配置文件中添加Redis相關(guān)的配置

#redis
# Redis服務(wù)器地址
redis.host= localhost
# Redis服務(wù)器連接端口
redis.port= 6379
redis.jedis.pool.max-active=
# 連接池中的最大空閑連接
redis.pool.max-idle= 8
# 連接池中的最小空閑連接
redis.pool.min-idle= 0
# 連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)
redis.pool.max-active= 8
# 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)
redis.pool.max-wait= -1
# 連接超時(shí)時(shí)間(毫秒)
redis.timeout= 0
redis.password=
步驟二

我們需要在pom.xml中添加Shiro集成Redis的依賴(lài)

<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相關(guān)配置中添加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開(kāi)源插件
     * @return
     */
    @Bean
    public RedisManager redisManager(RedisConfig redisConfig) {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost(redisConfig.getHost());
        redisManager.setPort(redisConfig.getPort());
        redisManager.setExpire(1800);// 配置緩存過(guò)期時(shí)間
        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;
    }
    /*
    創(chuàng)建安全管理器對(duì)象,關(guān)聯(lián)自定義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;
    }
    /**
     *  開(kāi)啟Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP掃描使用Shiro注解的類(lèi),并在必要時(shí)進(jìn)行安全邏輯驗(yàn)證
     * 配置以下兩個(gè)bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可實(shí)現(xiàn)此功能
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 開(kāi)啟aop注解支持
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

主要是在DefaultWebSecurityManager中需要配置對(duì)應(yīng)的sessionManager和CacheManager即可.
配置好之后偿枕,當(dāng)?shù)卿浲瓿设邓玻瑫?huì)在Redis中看到對(duì)應(yīng)的key.而且此時(shí)的緩存也交給了redis來(lái)處理了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市益老,隨后出現(xiàn)的幾起案子彪蓬,更是在濱河造成了極大的恐慌,老刑警劉巖捺萌,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件档冬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡桃纯,警方通過(guò)查閱死者的電腦和手機(jī)酷誓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)态坦,“玉大人盐数,你說(shuō)我怎么就攤上這事∩√荩” “怎么了玫氢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谜诫。 經(jīng)常有香客問(wèn)我漾峡,道長(zhǎng),這世上最難降的妖魔是什么喻旷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任生逸,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘槽袄。我一直安慰自己烙无,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布遍尺。 她就那樣靜靜地躺著截酷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狮鸭。 梳的紋絲不亂的頭發(fā)上合搅,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音歧蕉,去河邊找鬼。 笑死康铭,一個(gè)胖子當(dāng)著我的面吹牛惯退,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播从藤,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼催跪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了夷野?” 一聲冷哼從身側(cè)響起懊蒸,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎悯搔,沒(méi)想到半個(gè)月后骑丸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妒貌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年通危,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灌曙。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡菊碟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出在刺,到底是詐尸還是另有隱情逆害,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布蚣驼,位于F島的核電站魄幕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏隙姿。R本人自食惡果不足惜梅垄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧队丝,春花似錦靡馁、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至膘盖,卻和暖如春胧弛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侠畔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工结缚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人软棺。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓红竭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親喘落。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茵宪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容