SpringBoot + Shiro (四)緩存&記住密碼

最終demo

到這節(jié)為止,我們已經(jīng)實(shí)現(xiàn)了身份驗(yàn)證和權(quán)限驗(yàn)證。但是,如果我們登錄之后多次訪問http://localhost:8080/userInfo/userDel的話,會(huì)發(fā)現(xiàn)權(quán)限驗(yàn)證會(huì)每次都執(zhí)行一次。這是有問題的,因?yàn)橄裼脩舻臋?quán)限這些我們提供給shiro一次就夠了。

下面,我們開始給shiro添加緩存支持:

1.添加依賴

        <!-- shiro ehcache -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.2.2</version>
        </dependency>

        <!--
           包含支持UI模版(Velocity,F(xiàn)reeMarker,JasperReports),
           郵件服務(wù),
           腳本服務(wù)(JRuby),
           緩存Cache(EHCache),
           任務(wù)計(jì)劃Scheduling(uartz)。
        -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

2.注入緩存

com.example.demo.config.Shiro.ShiroConfiguration中添加以下方法。

    @Bean
    public EhCacheManager ehCacheManager() {
        System.out.println("ShiroConfiguration.getEhCacheManager()");
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
        return ehCacheManager;
    }

將緩存對(duì)象注入到SecurityManager中:

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setCacheManager(ehCacheManager()); //注入緩存對(duì)象。
        return securityManager;
    }

3.添加配置文件

在src/main/resouces/config中添加ehcache-shiro.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="es">

    <diskStore path="java.io.tmpdir"/>

    <!--
       name:緩存名稱。
       maxElementsInMemory:緩存最大數(shù)目
       maxElementsOnDisk:硬盤最大緩存?zhèn)€數(shù)。
       eternal:對(duì)象是否永久有效,一但設(shè)置了,timeout將不起作用。
       overflowToDisk:是否保存到磁盤,當(dāng)系統(tǒng)當(dāng)機(jī)時(shí)
       timeToIdleSeconds:設(shè)置對(duì)象在失效前的允許閑置時(shí)間(單位:秒)。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,可選屬性,默認(rèn)值是0,也就是可閑置時(shí)間無窮大。
       timeToLiveSeconds:設(shè)置對(duì)象在失效前允許存活時(shí)間(單位:秒)。最大時(shí)間介于創(chuàng)建時(shí)間和失效時(shí)間之間。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,默認(rèn)是0.,也就是對(duì)象存活時(shí)間無窮大。
       diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù) Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
       diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤緩存)的緩存區(qū)大小。默認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)。
       diskExpiryThreadIntervalSeconds:磁盤失效線程運(yùn)行時(shí)間間隔,默認(rèn)是120秒。
       memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí),Ehcache將會(huì)根據(jù)指定的策略去清理內(nèi)存。默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先出)或是LFU(較少使用)。
        clearOnFlush:內(nèi)存數(shù)量最大時(shí)是否清除。
         memoryStoreEvictionPolicy:
            Ehcache的三種清空策略;
            FIFO,first in first out,這個(gè)是大家最熟的,先進(jìn)先出。
            LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點(diǎn)就是講一直以來最少被使用的。如上面所講,緩存的元素有一個(gè)hit屬性,hit值最小的將會(huì)被清出緩存。
            LRU,Least Recently Used,最近最少使用的,緩存的元素有一個(gè)時(shí)間戳,當(dāng)緩存容量滿了,而又需要騰出地方來緩存新的元素的時(shí)候,那么現(xiàn)有緩存元素中時(shí)間戳離當(dāng)前時(shí)間最遠(yuǎn)的元素將被清出緩存。
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />


    <!-- 登錄記錄緩存鎖定10分鐘 -->
    <cache name="passwordRetryCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

啟動(dòng)項(xiàng)目,再多次訪問http://localhost:8080/userInfo/userDel,這時(shí)候只會(huì)在后臺(tái)打印一次配置權(quán)限的信息了,說明shiro緩存起了作用。

---------------------下面我們開始配置記住密碼-----------

1.在com.example.demo.config.Shiro.ShiroConfiguration中加入下面兩個(gè)方法:

    //cookie對(duì)象;
    @Bean
    public SimpleCookie rememberMeCookie() {
        System.out.println("ShiroConfiguration.rememberMeCookie()");
        //這個(gè)參數(shù)是cookie的名稱,對(duì)應(yīng)前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");

        //<!-- 記住我cookie生效時(shí)間30天 ,單位秒;-->
        simpleCookie.setMaxAge(259200);
        return simpleCookie;
    }

    //cookie管理對(duì)象;
    @Bean
    public CookieRememberMeManager cookieRememberMeManager() {
        System.out.println("ShiroConfiguration.rememberMeManager()");
        CookieRememberMeManager manager = new CookieRememberMeManager();
        manager.setCookie(rememberMeCookie());
        return manager;
    }

將rememberMeManager注入到SecurityManager中

@Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setCacheManager(ehCacheManager());
        securityManager.setRememberMeManager(cookieRememberMeManager()); //注入rememberMeManager;
        return securityManager;
    }

ShiroFilterFactoryBean中添加記住我過濾器user,添加user過濾器的資源在記住我或認(rèn)證之后就可以直接訪問了。

Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
...
        filterChainDefinitionMap.put("/index", "user");
        filterChainDefinitionMap.put("/", "user");
....

最后,在login.html頁(yè)面添加記住我單選框

<P><input type="checkbox" name="rememberMe" />記住我</P>

啟動(dòng)項(xiàng)目,正常登錄后關(guān)閉瀏覽器,再打開瀏覽器輸入http://localhost:8080/index,這時(shí)候就可以直接訪問index頁(yè)面,不需要再登錄了。

SpringBoot + Shiro (一)基礎(chǔ)工程搭建
SpringBoot + Shiro (二)身份校驗(yàn)和角色設(shè)置
SpringBoot + Shiro (三)權(quán)限
SpringBoot + Shiro (四)緩存&記住密碼
SpringBoot + Shiro (五)驗(yàn)證碼

最后,感謝幾位作者的文章解惑:
springboot整合shiro-登錄認(rèn)證和權(quán)限管理
Spring Boot Shiro權(quán)限管理【從零開始學(xué)Spring Boot】
Spring boot 中使用Shiro


最后幫朋友打個(gè)小廣告

一個(gè)有趣的迷你小程序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容