新聞中心
Shiro是一個(gè)優(yōu)秀的Java安全框架,通過(guò)Shiro的使用可以簡(jiǎn)化Java應(yīng)用程序的安全開(kāi)發(fā),加快應(yīng)用程序的開(kāi)發(fā)速度。然而,在使用Shiro時(shí)需要注意數(shù)據(jù)庫(kù)的更新問(wèn)題,否則會(huì)出現(xiàn)一些意想不到的問(wèn)題。本文將詳細(xì)介紹Shiro安全框架數(shù)據(jù)庫(kù)更新的注意事項(xiàng)。

一、 對(duì)Shiro權(quán)限管理表的更新
在使用Shiro時(shí),需要?jiǎng)?chuàng)建Shiro權(quán)限管理表,例如:user、role、permission等表。這些表記錄了用戶、角色、權(quán)限等相關(guān)信息。當(dāng)對(duì)Shiro權(quán)限管理表進(jìn)行更新時(shí),需要注意以下幾個(gè)問(wèn)題。
1. 遷移數(shù)據(jù)
當(dāng)需要更新Shiro權(quán)限管理表結(jié)構(gòu)時(shí),需要先遷移舊數(shù)據(jù)到新表結(jié)構(gòu)中,否則會(huì)導(dǎo)致數(shù)據(jù)丟失,用戶、角色、權(quán)限等信息都無(wú)法被正確處理。因此,必須在不影響原有應(yīng)用程序的情況下,將舊數(shù)據(jù)移動(dòng)到新的數(shù)據(jù)表中。
2. 檢測(cè)表關(guān)聯(lián)關(guān)系
在更新Shiro權(quán)限管理表結(jié)構(gòu)時(shí),需要關(guān)注表之間的關(guān)聯(lián)關(guān)系,否則會(huì)出現(xiàn)關(guān)聯(lián)數(shù)據(jù)不匹配的情況。例如,如果在更新Shiro角色表時(shí),沒(méi)有考慮到該表和其他表之間的關(guān)聯(lián)關(guān)系,則會(huì)導(dǎo)致角色關(guān)聯(lián)的用戶數(shù)據(jù)出現(xiàn)問(wèn)題。
3. 更新表結(jié)構(gòu)
在更新Shiro權(quán)限管理表結(jié)構(gòu)時(shí),需要小心修改表結(jié)構(gòu),避免出現(xiàn)不兼容的問(wèn)題。例如,如果刪除了某個(gè)字段,而該字段在應(yīng)用程序中被引用,則會(huì)導(dǎo)致應(yīng)用程序無(wú)法正常工作。
二、Shiro緩存更新
Shiro安全框架以緩存來(lái)提高性能,緩存分為權(quán)限緩存和會(huì)話緩存。Shiro權(quán)限緩存基于用戶、角色和權(quán)限信息,緩存這些信息提高Shiro性能。Shiro會(huì)話緩存則是緩存Shiro會(huì)話,會(huì)話緩存可以顯著提高應(yīng)用程序性能。當(dāng)需要更新緩存時(shí),需要注意以下幾個(gè)問(wèn)題。
1. 更新頻率
在更新緩存時(shí),需要注意更新頻率的問(wèn)題,過(guò)于頻繁的緩存更新會(huì)導(dǎo)致性能下降,因此需要根據(jù)實(shí)際情況,選擇合適的緩存更新頻率。
2. 緩存清除
在緩存更新過(guò)程中,需要清除緩存中舊的數(shù)據(jù),否則會(huì)導(dǎo)致數(shù)據(jù)混亂。例如,當(dāng)用戶密碼被更新時(shí),需要清除緩存中該用戶的舊密碼數(shù)據(jù),否則用戶登錄時(shí)會(huì)出現(xiàn)認(rèn)證失敗的問(wèn)題。
3. 緩存更新機(jī)制
在更新緩存時(shí)需要考慮緩存更新機(jī)制,例如,當(dāng)Shiro權(quán)限緩存更新時(shí),需要考慮權(quán)限緩存數(shù)據(jù)的同步。即,當(dāng)用戶、角色或權(quán)限表發(fā)生變更時(shí),需要清除舊的權(quán)限緩存,并重新緩存新的權(quán)限數(shù)據(jù)。
三、Shiro密碼加密算法更新
在使用Shiro時(shí),需要對(duì)密碼進(jìn)行加密。Shiro提供了多種密碼加密算法,如MD5和SHA-1等。當(dāng)需要修改密碼加密算法時(shí),需要注意以下幾個(gè)問(wèn)題。
1. 算法兼容性
在修改密碼加密算法時(shí)需要注意算法的兼容性問(wèn)題,如果在應(yīng)用程序中采用了新的密碼加密算法,而Shiro權(quán)限管理表中保存的密碼使用的是舊的密碼加密算法,則會(huì)導(dǎo)致密碼無(wú)法匹配,用戶無(wú)法認(rèn)證。
2. 數(shù)據(jù)庫(kù)升級(jí)腳本
在修改密碼加密算法后,需要將權(quán)限管理表中舊的密碼數(shù)據(jù)轉(zhuǎn)換為新的密碼加密算法。因此,在密碼加密算法更新時(shí),需要同時(shí)更新數(shù)據(jù)庫(kù)升級(jí)腳本,以便實(shí)現(xiàn)舊密碼數(shù)據(jù)的轉(zhuǎn)換。
四、結(jié)論
Shiro安全框架是一個(gè)極具擴(kuò)展性的Java安全框架,但是在使用Shiro時(shí),需要特別注意數(shù)據(jù)庫(kù)更新問(wèn)題,避免出現(xiàn)數(shù)據(jù)丟失和應(yīng)用程序無(wú)法正常工作的問(wèn)題。因此,在更新Shiro數(shù)據(jù)庫(kù)時(shí),需要認(rèn)真對(duì)待,并充分測(cè)試,以確保Shiro安全框架正常運(yùn)行。
相關(guān)問(wèn)題拓展閱讀:
- java框架有哪些常用框架
- Shiro的 rememberMe 功能使用指導(dǎo)為什么rememberMe設(shè)置了沒(méi)作用
java框架有哪些常用框架
十大常用框架:
一、SpringMVC
二、Spring
三、Mybatis
四、Dubbo
五、Maven
六、RabbitMQ
七、Log4j
八、Ehcache
九、Redis
十、Shiro
延展閱讀:
一、SpringMVC
SpringWebMVC是一種基于Java的實(shí)現(xiàn)了WebMVC設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將web層進(jìn)行職責(zé)解耦,基于請(qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡(jiǎn)化開(kāi)發(fā),SpringWebMVC也是要簡(jiǎn)化我們?nèi)粘eb開(kāi)發(fā)的。
模型(Model)封裝了應(yīng)用程序的數(shù)據(jù)和一般他們會(huì)組成的POJO。
視圖(View)是負(fù)責(zé)呈現(xiàn)模型數(shù)據(jù)和一般它生成的HTML輸出,客戶端的瀏覽器能夠解釋。
控制器(Controller)負(fù)責(zé)處理用戶的請(qǐng)求,并建立適當(dāng)?shù)哪P?,并把它傳遞給視圖渲染。
Spring的web模型-視圖-控制器(MVC)框架是圍繞著處理所有的HTTP請(qǐng)求和響應(yīng)的的設(shè)計(jì)。
SpringWebMVC處理請(qǐng)求的流程
具體執(zhí)行步驟如下:
1、首先用戶發(fā)送請(qǐng)求————>前端控制器,前端控制器根據(jù)請(qǐng)求信息(如URL)來(lái)決定選擇哪一個(gè)頁(yè)面控制器進(jìn)行處理并把請(qǐng)求委托給它,即以前的控制器的控制邏輯部分;圖2-1中的1、2步驟;
2、頁(yè)面控制器接收到請(qǐng)求后,進(jìn)行功能處理,首先需要收集和綁定請(qǐng)求參數(shù)到一個(gè)對(duì)象,這個(gè)對(duì)象在SpringWebMVC中叫命令對(duì)象,并進(jìn)行驗(yàn)證,然后將命令對(duì)象委托給業(yè)務(wù)對(duì)塌寬知象進(jìn)行處理;處理完畢后返回一個(gè)(模型數(shù)據(jù)和邏輯視圖名);圖2-1中的3、4、5步驟;
3、前端控制器收回控制權(quán),然后根據(jù)返回的邏輯視圖名,選擇相應(yīng)的視圖進(jìn)行渲染,并把模型數(shù)據(jù)傳入以便視圖渲染;圖2-1中的步驟6、7;
4、前端控制器再次收回控制權(quán),將響應(yīng)返回給用戶,圖2-1中的步驟8;至此整個(gè)結(jié)束。
二、Spring
2.1、IOC容器:wwwblogs/linjiqin/archive/2023/11/04/.html
IOC容器就是具有依賴注入功能的容器,IOC容器負(fù)責(zé)實(shí)例化、定位、巧和配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴。應(yīng)用程序無(wú)需直接在代碼中new相關(guān)的對(duì)象,應(yīng)用程序由IOC容器進(jìn)行組裝。在Spring中BeanFactory是IOC容器的實(shí)際代表者。
2.2、AOP:blog.csdn.net/moreevan/article/details/
簡(jiǎn)單地說(shuō),就是將那些與業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可操作性團(tuán)消和可維護(hù)性。AOP代表的是一個(gè)橫向的關(guān)系
AOP用來(lái)封裝橫切關(guān)注點(diǎn),具體可以在下面的場(chǎng)景中使用:
權(quán)限
Caching緩存
Contextpassing內(nèi)容傳遞
Errorhandling錯(cuò)誤處理
Lazyloading懶加載
Debugging調(diào)試
logging,tracing,profilingandmonitoring記錄跟蹤優(yōu)化校準(zhǔn)
Performance性能優(yōu)化
Persistence持久化
Resourcepooling資源池
同步
事務(wù)
三、Mybatis
MyBatis是支持普通SQL查詢,存儲(chǔ)過(guò)程和高級(jí)映射的優(yōu)秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及結(jié)果集的檢索。MyBatis使用簡(jiǎn)單的XML或注解用于配置和原始映射,將接口和Java的POJOs(PlainOldJavaObjects,普通的Java對(duì)象)映射成數(shù)據(jù)庫(kù)中的記錄。
總體流程:
(1)加載配置并初始化
觸發(fā)條件:加載配置文件
將SQL的配置信息加載成為一個(gè)個(gè)對(duì)象(包括了傳入?yún)?shù)映射配置、執(zhí)行的SQL語(yǔ)句、結(jié)果映射配置),存儲(chǔ)在內(nèi)存中。
(2)接收調(diào)用請(qǐng)求
觸發(fā)條件:調(diào)用Mybatis提供的API
傳入?yún)?shù):為SQL的ID和傳入?yún)?shù)對(duì)象
處理過(guò)程:將請(qǐng)求傳遞給下層的請(qǐng)求處理層進(jìn)行處理。
(3)處理操作請(qǐng)求觸發(fā)條件:API接口層傳遞請(qǐng)求過(guò)來(lái)
傳入?yún)?shù):為SQL的ID和傳入?yún)?shù)對(duì)象
處理過(guò)程:
(A)根據(jù)SQL的ID查找對(duì)應(yīng)的對(duì)象。
(B)根據(jù)傳入?yún)?shù)對(duì)象解析對(duì)象,得到最終要執(zhí)行的SQL和執(zhí)行傳入?yún)?shù)。
(C)獲取數(shù)據(jù)庫(kù)連接,根據(jù)得到的最終SQL語(yǔ)句和執(zhí)行傳入?yún)?shù)到數(shù)據(jù)庫(kù)執(zhí)行,并得到執(zhí)行結(jié)果。
(D)根據(jù)對(duì)象中的結(jié)果映射配置對(duì)得到的執(zhí)行結(jié)果進(jìn)行轉(zhuǎn)換處理,并得到最終的處理結(jié)果。
(E)釋放連接資源。
(4)返回處理結(jié)果將最終的處理結(jié)果返回。
MyBatis最強(qiáng)大的特性之一就是它的動(dòng)態(tài)語(yǔ)句功能。如果您以前有使用JDBC或者類似框架的經(jīng)歷,您就會(huì)明白把SQL語(yǔ)句條件連接在一起是多么的痛苦,要確保不能忘記空格或者不要在columns列后面省略一個(gè)逗號(hào)等。動(dòng)態(tài)語(yǔ)句能夠完全解決掉這些痛苦。
四、Dubbo
Dubbo是一個(gè)分布式服務(wù)框架,致力于提供高性能和透明化的RPC(遠(yuǎn)程過(guò)程調(diào)用協(xié)議)遠(yuǎn)程服務(wù)調(diào)用方案,以及SOA服務(wù)治理方案。簡(jiǎn)單的說(shuō),bbo就是個(gè)服務(wù)框架,如果沒(méi)有分布式的需求,其實(shí)是不需要用的,只有在分布式的時(shí)候,才有bbo這樣的分布式服務(wù)框架的需求,并且本質(zhì)上是個(gè)服務(wù)調(diào)用的東東,說(shuō)白了就是個(gè)遠(yuǎn)程服務(wù)調(diào)用的分布式框架。
1、透明化的遠(yuǎn)程方法調(diào)用,就像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法,只需簡(jiǎn)單配置,沒(méi)有任何API侵入。
2、軟負(fù)載均衡及容錯(cuò)機(jī)制,可在內(nèi)網(wǎng)替代F5等硬件負(fù)載均衡器,降低成本,減少單點(diǎn)。
3、服務(wù)自動(dòng)注冊(cè)與發(fā)現(xiàn),不再需要寫(xiě)死服務(wù)提供方地址,注冊(cè)中心基于接口名查詢服務(wù)提供者的IP地址,并且能夠平滑添加或刪除服務(wù)提供者。
節(jié)點(diǎn)角色說(shuō)明:
Provider:暴露服務(wù)的服務(wù)提供方。
Consumer:調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方。
Registry:服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心。
Monitor:統(tǒng)計(jì)服務(wù)的調(diào)用次調(diào)和調(diào)用時(shí)間的監(jiān)控中心。
Container:服務(wù)運(yùn)行容器。
五、Maven
Maven這個(gè)個(gè)項(xiàng)目管理和構(gòu)建自動(dòng)化工具,越來(lái)越多的開(kāi)發(fā)人員使用它來(lái)管理項(xiàng)目中的jar包。但是對(duì)于我們程序員來(lái)說(shuō),我們最關(guān)心的是它的項(xiàng)目構(gòu)建功能。
六、RabbitMQ
消息隊(duì)列一般是在項(xiàng)目中,將一些無(wú)需即時(shí)返回且耗時(shí)的操作提取出來(lái),進(jìn)行了異步處理,而這種異步處理的方式大大的節(jié)省了服務(wù)器的請(qǐng)求響應(yīng)時(shí)間,從而提高了系統(tǒng)的吞吐量。
RabbitMQ是用Erlang實(shí)現(xiàn)的一個(gè)高并發(fā)高可靠AMQP消息隊(duì)列服務(wù)器。
Erlang是一門(mén)動(dòng)態(tài)類型的函數(shù)式編程語(yǔ)言。對(duì)應(yīng)到Erlang里,每個(gè)Actor對(duì)應(yīng)著一個(gè)Erlang進(jìn)程,進(jìn)程之間通過(guò)消息傳遞進(jìn)行通信。相比共享內(nèi)存,進(jìn)程間通過(guò)消息傳遞來(lái)通信帶來(lái)的直接好處就是消除了直接的鎖開(kāi)銷(不考慮Erlang虛擬機(jī)底層實(shí)現(xiàn)中的鎖應(yīng)用)。
AMQP(AdvancedMessageQueueProtocol)定義了一種消息系統(tǒng)規(guī)范。這個(gè)規(guī)范描述了在一個(gè)分布式的系統(tǒng)中各個(gè)子系統(tǒng)如何通過(guò)消息交互。
七、Log4j
日志記錄的優(yōu)先級(jí),分為OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定義的級(jí)別。
八、Ehcache
EhCache是一個(gè)純Java的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn),是Hibernate中默認(rèn)的。Ehcache是一種廣泛使用的開(kāi)源Java分布式緩存。主要面向通用緩存,JavaEE和輕量級(jí)容器。它具有內(nèi)存和磁盤(pán)存儲(chǔ),緩存加載器,緩存擴(kuò)展,緩存異常處理程序,一個(gè)gzip緩存servlet過(guò)濾器,支持REST和SOAPapi等特點(diǎn)。
優(yōu)點(diǎn):
1、快速
2、簡(jiǎn)單
3、多種緩存策略
4、緩存數(shù)據(jù)有兩級(jí):內(nèi)存和磁盤(pán),因此無(wú)需擔(dān)心容量問(wèn)題
5、緩存數(shù)據(jù)會(huì)在虛擬機(jī)重啟的過(guò)程中寫(xiě)入磁盤(pán)
6、可以通過(guò)RMI、可插入API等方式進(jìn)行分布式緩存
7、具有緩存和緩存管理器的偵聽(tīng)接口
8、支持多緩存管理器實(shí)例,以及一個(gè)實(shí)例的多個(gè)緩存區(qū)域
9、提供Hibernate的緩存實(shí)現(xiàn)
缺點(diǎn):
1、使用磁盤(pán)Cache的時(shí)候非常占用磁盤(pán)空間:這是因?yàn)镈iskCache的算法簡(jiǎn)單,該算法簡(jiǎn)單也導(dǎo)致Cache的效率非常高。它只是對(duì)元素直接追加存儲(chǔ)。因此搜索元素的時(shí)候非常的快。如果使用DiskCache的,在很頻繁的應(yīng)用中,很快磁盤(pán)會(huì)滿。
2、不能保證數(shù)據(jù)的安全:當(dāng)突然kill掉java的時(shí)候,可能會(huì)產(chǎn)生沖突,EhCache的解決方法是如果文件沖突了,則重建cache。這對(duì)于Cache數(shù)據(jù)需要保存的時(shí)候可能不利。當(dāng)然,Cache只是簡(jiǎn)單的加速,而不能保證數(shù)據(jù)的安全。如果想保證數(shù)據(jù)的存儲(chǔ)安全,可以使用BekeleyDBJavaEdition版本。這是個(gè)嵌入式數(shù)據(jù)庫(kù)。可以確保存儲(chǔ)安全和空間的利用率。
九、Redis
redis是一個(gè)key-value存儲(chǔ)系統(tǒng)。和Memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)、list(鏈表)、set()、zset(sortedset_有序)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫(xiě)入磁盤(pán)或者把修改操作寫(xiě)入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步。
Redis數(shù)據(jù)庫(kù)完全在內(nèi)存中,使用磁盤(pán)僅用于持久性。相比許多鍵值數(shù)據(jù)存儲(chǔ),Redis擁有一套較為豐富的數(shù)據(jù)類型。Redis可以將數(shù)據(jù)復(fù)制到任意數(shù)量的從服務(wù)器。
1.2、Redis優(yōu)點(diǎn):
(1)異??焖伲篟edis的速度非常快,每秒能執(zhí)行約11萬(wàn),每秒約81000條記錄。
(2)支持豐富的數(shù)據(jù)類型:Redis支持更大多數(shù)開(kāi)發(fā)人員已經(jīng)知道像列表,,有序,散列數(shù)據(jù)類型。這使得它非常容易解決各種各樣的問(wèn)題,因?yàn)槲覀冎滥男﹩?wèn)題是可以處理通過(guò)它的數(shù)據(jù)類型更好。
(3)操作都是原子性:所有Redis操作是原子的,這保證了如果兩個(gè)客戶端同時(shí)訪問(wèn)的Redis服務(wù)器將獲得更新后的值。
(4)多功能實(shí)用工具:Redis是一個(gè)多實(shí)用的工具,可以在多個(gè)用例如緩存,消息,隊(duì)列使用(Redis原生支持發(fā)布/訂閱),任何短暫的數(shù)據(jù),應(yīng)用程序,如Web應(yīng)用程序會(huì)話,網(wǎng)頁(yè)命中計(jì)數(shù)等。
1.3、Redis缺點(diǎn):
(1)單線程
(2)耗內(nèi)存
十、Shiro
ApacheShiro是Java的一個(gè)安全框架,旨在簡(jiǎn)化身份驗(yàn)證和授權(quán)。Shiro在JavaSE和JavaEE項(xiàng)目中都可以使用。它主要用來(lái)處理身份認(rèn)證,授權(quán),企業(yè)會(huì)話管理和加密等。Shiro的具體功能點(diǎn)如下:
(1)身份認(rèn)證/登錄,驗(yàn)證用戶是不是擁有相應(yīng)的身份;
(2)授權(quán),即權(quán)限驗(yàn)證,驗(yàn)證某個(gè)已認(rèn)證的用戶是否擁有某個(gè)權(quán)限;即判斷用戶是否能做事情,常見(jiàn)的如:驗(yàn)證某個(gè)用戶是否擁有某個(gè)角色?;蛘呒?xì)粒度的驗(yàn)證某個(gè)用戶對(duì)某個(gè)資源是否具有某個(gè)權(quán)限;
(3)會(huì)話管理,即用戶登錄后就是一次會(huì)話,在沒(méi)有退出之前,它的所有信息都在會(huì)話中;會(huì)話可以是普通JavaSE環(huán)境的,也可以是如Web環(huán)境的;
(4)加密,保護(hù)數(shù)據(jù)的安全性,如密碼加密存儲(chǔ)到數(shù)據(jù)庫(kù),而不是明文存儲(chǔ);
(5)Web支持,可以非常容易的集成到Web環(huán)境;
Caching:緩存,比如用戶登錄后,其用戶信息、擁有的角色/權(quán)限不必每次去查,這樣可以提高效率;
(6)shiro支持多線程應(yīng)用的并發(fā)驗(yàn)證,即如在一個(gè)線程中開(kāi)啟另一個(gè)線程,能把權(quán)限自動(dòng)傳播過(guò)去;
(7)提供測(cè)試支持;
(8)允許一個(gè)用戶假裝為另一個(gè)用戶(如果他們?cè)试S)的身份進(jìn)行訪問(wèn);
(9)記住我,這個(gè)是非常常見(jiàn)的功能,即一次登錄后,下次再來(lái)的話不用登錄了。
Shiro的 rememberMe 功能使用指導(dǎo)為什么rememberMe設(shè)置了沒(méi)作用
官方清缺的文檔有說(shuō)明,isRemembered和isAuthenticated是互斥的
isRemembered是在服務(wù)器上記錄一個(gè)cookie說(shuō)明你這個(gè)用戶登陸過(guò)并答塌辯且被記住了
效果類似于亞馬遜頁(yè)面上,他會(huì)記衫孝住近期登陸過(guò)的用戶(Subject)
但是你進(jìn)行敏感操作的時(shí)候還是要重新登錄敲賬號(hào)密碼的,也就是必須重新進(jìn)行Authentication
也就是說(shuō)如果你的攔截器配置了authc或者其他需要認(rèn)證之后才能使用的
shiro的rememberMe功能就不起作用了
印象中有一個(gè)url攔截器可以過(guò)濾這個(gè),不記得名字了
采用這個(gè)解決方案的前提是,你必須自己先實(shí)現(xiàn)一個(gè)realm,不過(guò)這個(gè)我相信大家都會(huì)實(shí)現(xiàn)的,畢竟默認(rèn)的不是jdbcRealm ,真正的項(xiàng)目都是要查數(shù)據(jù)庫(kù)才能確定用戶是否登錄的。那么我就假定大家的項(xiàng)目中都有那么一個(gè)負(fù)責(zé)驗(yàn)證登錄的 JdbcRealm, 并且是采用用戶名密碼認(rèn)證的,在 doGetAuthenticationInfo 方法里面是采用如下的方轎枯穗法來(lái)做認(rèn)證
…
info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());
這個(gè)前提條件保證你的閉卜principal是username,相信大部分人根據(jù)教程做shiro的時(shí)候都采用了這種方式
STEP1 復(fù)寫(xiě) FormAuthenticationFilter 的 isAccessAllowed 方法敗枯
做一個(gè)新類繼承FormAuthenticationFilter ,并復(fù)寫(xiě) isAccessAllowed 方法
package com.yqr.jxc.shiro;
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import com.yqr.jxc.service.global.GlobalUserService;
public class RememberAuthenticationFilter extends FormAuthenticationFilter {
@Resource(name=”globalUserService”)
private GlobalUserService globalUserService;
/**
* 這個(gè)方法決定了是否能讓用戶登錄
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
Subject subject = getSubject(request, response);
//如果 isAuthenticated 為 false 證明不是登錄過(guò)的,同時(shí) isRememberd 為true 證明是沒(méi)登陸直接通過(guò)記住我功能進(jìn)來(lái)的
if(!subject.isAuthenticated() && subject.isRemembered()){
//獲取session看看是不是空的
Session session = subject.getSession(true);
//隨便拿session的一個(gè)屬性來(lái)看session當(dāng)前是否是空的,我用userId,你們的項(xiàng)目可以自行發(fā)揮
if(session.getAttribute(“userId”) == null){
//如果是空的才初始化,否則每次都要初始化,項(xiàng)目得慢死
//這邊根據(jù)前面的前提假設(shè),拿到的是username
String username = subject.getPrincipal().toString();
//在這個(gè)方法里面做初始化用戶上下文的事情,比如通過(guò)查詢數(shù)據(jù)庫(kù)來(lái)設(shè)置session值,你們自己發(fā)揮
globalUserService.initUserContext(username, subject);
}
}
//這個(gè)方法本來(lái)只返回 subject.isAuthenticated() 現(xiàn)在我們加上 subject.isRemembered() 讓它同時(shí)也兼容remember這種情況
return subject.isAuthenticated() || subject.isRemembered();
}
}
STEP2 設(shè)置使用這個(gè)新的 AuthenticationFilter (認(rèn)證過(guò)濾器)
如果你用的是spring那么
…
/** = rememberAuthFilter
…
如果你用的是 ini 文件,那么
rememberAuthFilter=com.yqr.jxc.shiro.RememberAuthenticationFilter
#將之前的 /** = authc 替換成 rememberAuthFilter
…
/** = rememberAuthFilter
然后重啟項(xiàng)目我們來(lái)測(cè)試一下,先登錄一次系統(tǒng),然后直接關(guān)掉瀏覽器,然后打開(kāi)瀏覽器直接輸入系統(tǒng)某個(gè)頁(yè)面的地址,發(fā)現(xiàn)可以直接進(jìn)去了,session什么的也設(shè)置好了
成都服務(wù)器租用選創(chuàng)新互聯(lián),先試用再開(kāi)通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡(jiǎn)單好用,價(jià)格厚道的香港/美國(guó)云服務(wù)器和獨(dú)立服務(wù)器。物理服務(wù)器托管租用:四川成都、綿陽(yáng)、重慶、貴陽(yáng)機(jī)房服務(wù)器托管租用。
當(dāng)前題目:Shiro安全框架:數(shù)據(jù)庫(kù)更新注意事項(xiàng) (shiro更新數(shù)據(jù)庫(kù))
地址分享:http://m.fisionsoft.com.cn/article/dhjooge.html


咨詢
建站咨詢
