Java中security與shiro的區(qū)別詳解
一、Shiro與spring security 比較 shiro
1.框架原理圖及名詞解釋
名詞解釋
- **subject:**主體,可以是用戶(hù)也可以是程序,主體要訪問(wèn)系統(tǒng),系統(tǒng)需要對(duì)主體進(jìn)行認(rèn)證、授權(quán)。
- securityManager:安全管理器,主體進(jìn)行認(rèn)證和授權(quán)都是通過(guò)securityManager進(jìn)行。它包含下面的認(rèn)證器和授權(quán)器。
- authenticator:認(rèn)證器,主體進(jìn)行認(rèn)證最終通過(guò)authenticator進(jìn)行的。
- authorizer:授權(quán)器,主體進(jìn)行授權(quán)最終通過(guò)authorizer進(jìn)行的。
- sessionManager:web應(yīng)用中一般是用web容器對(duì)session進(jìn)行管理,shiro也提供一套session管理的方式??梢詫?shí)現(xiàn)單點(diǎn)登錄。
- SessionDao:通過(guò)SessionDao管理session數(shù)據(jù),針對(duì)個(gè)性化的session數(shù)據(jù)存儲(chǔ)需要使用sessionDao。
- cache Manager:緩存管理器,主要對(duì)session和授權(quán)數(shù)據(jù)進(jìn)行緩存,比如將授權(quán)數(shù)據(jù)通過(guò)cacheManager進(jìn)行緩存管理,和ehcache整合對(duì)緩存數(shù)據(jù)進(jìn)行管理。
- realm:域,領(lǐng)域,相當(dāng)于數(shù)據(jù)源,通過(guò)realm存取認(rèn)證、授權(quán)相關(guān)數(shù)據(jù)。(它的主要目的是與數(shù)據(jù)庫(kù)打交道,查詢(xún)數(shù)據(jù)庫(kù)中的認(rèn)證的信息(比如用戶(hù)名和密碼),查詢(xún)授權(quán)的信息(比如權(quán)限的code等,所以這里可以理解為調(diào)用數(shù)據(jù)庫(kù)查詢(xún)一系列的信息,一般情況下在項(xiàng)目中采用自定義的realm,因?yàn)椴煌臉I(yè)務(wù)需求不一樣))
注意:在realm中存儲(chǔ)授權(quán)和認(rèn)證的邏輯。
- **cryptography:**密碼管理,提供了一套加密/解密的組件,方便開(kāi)發(fā)。比如提供常用的散列、加/解密等功能,比如md5散列算法。
認(rèn)證原理圖
subject(主體)請(qǐng)求認(rèn)證,調(diào)用subject.login(token)
SecurityManager(安全管理器)執(zhí)行認(rèn)證
SecurityManager通過(guò)ModularRealmAuthenticator進(jìn)行認(rèn)證。
ModularRealmAuthenticator將token傳給realm,realm根據(jù)token中用戶(hù)信息從數(shù)據(jù)庫(kù)查詢(xún)用戶(hù)信息(包括身份和憑證),realm如果查詢(xún)不到用戶(hù)給ModularRealmAuthenticator返回null,ModularRealmAuthenticator拋出異常(用戶(hù)不存在),realm如果查詢(xún)到用戶(hù)給ModularRealmAuthenticator返回AuthenticationInfo(認(rèn)證信息),ModularRealmAuthenticator拿著AuthenticationInfo(認(rèn)證信息)去進(jìn)行憑證(密碼)比對(duì)。如果一致則認(rèn)證通過(guò),如果不致拋出異常(憑證錯(cuò)誤)。
授權(quán)原理圖
授權(quán)流程
對(duì)subject進(jìn)行授權(quán),調(diào)用方法isPermitted(“”)或者h(yuǎn)asRole(“”)
SecurityManager執(zhí)行授權(quán),通過(guò)ModularRealmAuthorizer執(zhí)行授權(quán)
ModularRealmAuthorizer執(zhí)行realm(自定義的CustomRealm)從數(shù)據(jù)庫(kù)查詢(xún)權(quán)限數(shù)據(jù)調(diào)用realm的授權(quán)方法:doGetAuthorizationInfo
realm從數(shù)據(jù)庫(kù)查詢(xún)權(quán)限數(shù)據(jù),返回ModularRealmAuthorizer
ModularRealmAuthorizer調(diào)用PermissionResolver進(jìn)行權(quán)限串比對(duì)
如果比對(duì)后,isPermitted中"permission串"在realm查詢(xún)到權(quán)限數(shù)據(jù)中,說(shuō)明用戶(hù)訪問(wèn)permission串有權(quán)限,否則沒(méi)有權(quán)限,拋出異常。
二、Spring Security簡(jiǎn)介
Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架。它提供了一組可以在Spring應(yīng)用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉(zhuǎn)Inversion of Control ,DI:Dependency Injection 依賴(lài)注入)和AOP(面向切面編程)功能,為應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制功能,減少了為企業(yè)系統(tǒng)安全控制編寫(xiě)大量重復(fù)代碼的工作。它是一個(gè)輕量級(jí)的安全框架,它確保基于Spring的應(yīng)用程序提供身份驗(yàn)證和授權(quán)支持。它與Spring MVC有很好地集成,并配備了流行的安全算法實(shí)現(xiàn)捆綁在一起。安全主要包括兩個(gè)操作“認(rèn)證”與“驗(yàn)證”(有時(shí)候也會(huì)叫做權(quán)限控制)。“認(rèn)證”是為用戶(hù)建立一個(gè)其聲明的角色的過(guò)程,這個(gè)角色可以一個(gè)用戶(hù)、一個(gè)設(shè)備或者一個(gè)系統(tǒng)。“驗(yàn)證”指的是一個(gè)用戶(hù)在你的應(yīng)用中能夠執(zhí)行某個(gè)操作。在到達(dá)授權(quán)判斷之前,角色已經(jīng)在身份認(rèn)證過(guò)程中建立了。
它的設(shè)計(jì)是基于框架內(nèi)大范圍的依賴(lài)的,可以被劃分為以下幾塊。
核心組件
1.SecurityContextHolder
SecurityContextHolder它持有的是安全上下文(security context)的信息。當(dāng)前操作的用戶(hù)是誰(shuí),該用戶(hù)是否已經(jīng)被認(rèn)證,他擁有哪些角色權(quán)等等,這些都被保存在SecurityContextHolder中。SecurityContextHolder默認(rèn)使用ThreadLocal 策略來(lái)存儲(chǔ)認(rèn)證信息??吹絋hreadLocal 也就意味著,這是一種與線(xiàn)程綁定的策略。在web環(huán)境下,Spring Security在用戶(hù)登錄時(shí)自動(dòng)綁定認(rèn)證信息到當(dāng)前線(xiàn)程,在用戶(hù)退出時(shí),自動(dòng)清除當(dāng)前線(xiàn)程的認(rèn)證信息。
2.SecurityContext
安全上下文,主要持有Authentication對(duì)象,如果用戶(hù)未鑒權(quán),那Authentication對(duì)象將會(huì)是空的。該示例可以通過(guò)SecurityContextHolder.getContext靜態(tài)方法獲取。
3.Authentication
鑒權(quán)對(duì)象,該對(duì)象主要包含了用戶(hù)的詳細(xì)信息(UserDetails)和用戶(hù)鑒權(quán)時(shí)所需要的信息,如用戶(hù)提交的用戶(hù)名密碼、Remember-me Token,或者digest hash值等,按不同鑒權(quán)方式使用不同的Authentication實(shí)現(xiàn)。
Authentication是spring security包中的接口,直接繼承自Principal類(lèi),而Principal是位于java.security包中的??梢砸?jiàn)得,Authentication在spring security中是最高級(jí)別的身份/認(rèn)證的抽象。由這個(gè)頂級(jí)接口,我們可以得到用戶(hù)擁有的權(quán)限信息列表,密碼,用戶(hù)細(xì)節(jié)信息,用戶(hù)身份信息,認(rèn)證信息。
4.GrantedAuthority
該接口表示了當(dāng)前用戶(hù)所擁有的權(quán)限(或者角色)信息。這些信息有授權(quán)負(fù)責(zé)對(duì)象AccessDecisionManager來(lái)使用,并決定最終用戶(hù)是否可以訪問(wèn)某資源(URL或方法調(diào)用或域?qū)ο螅hb權(quán)時(shí)并不會(huì)使用到該對(duì)象。
5.UserDetails
這個(gè)接口規(guī)范了用戶(hù)詳細(xì)信息所擁有的字段,譬如用戶(hù)名、密碼、賬號(hào)是否過(guò)期、是否鎖定等。在Spring Security中,獲取當(dāng)前登錄的用戶(hù)的信息,一般情況是需要在這個(gè)接口上面進(jìn)行擴(kuò)展,用來(lái)對(duì)接自己系統(tǒng)的用戶(hù)
6.UserDetailsService
這個(gè)接口只提供一個(gè)接口loadUserByUsername(String username),這個(gè)接口非常重要,一般情況我們都是通過(guò)擴(kuò)展這個(gè)接口來(lái)顯示獲取我們的用戶(hù)信息,用戶(hù)登錄時(shí)傳遞的用戶(hù)名和密碼也是通過(guò)這里這查找出來(lái)的用戶(hù)名和密碼進(jìn)行校驗(yàn),但是真正的校驗(yàn)不在這里,而是由AuthenticationManager以及AuthenticationProvider負(fù)責(zé)的,需要強(qiáng)調(diào)的是,如果用戶(hù)不存在,不應(yīng)返回NULL,而要拋出異常UsernameNotFoundException
7.AuthenticationManager
AuthenticationManager(接口)是認(rèn)證相關(guān)的核心接口,也是發(fā)起認(rèn)證的出發(fā)點(diǎn),因?yàn)樵趯?shí)際需求中,我們可能會(huì)允許用戶(hù)使用用戶(hù)名+密碼登錄,同時(shí)允許用戶(hù)使用郵箱+密碼,手機(jī)號(hào)碼+密碼登錄,甚至,可能允許用戶(hù)使用指紋登錄(還有這樣的操作?沒(méi)想到吧),所以說(shuō)AuthenticationManager一般不直接認(rèn)證,AuthenticationManager接口的常用實(shí)現(xiàn)類(lèi)ProviderManager 內(nèi)部會(huì)維護(hù)一個(gè)List列表,存放多種認(rèn)證方式,實(shí)際上這是委托者模式的應(yīng)用(Delegate)。也就是說(shuō),核心的認(rèn)證入口始終只有一個(gè):AuthenticationManager,不同的認(rèn)證方式:用戶(hù)名+密碼(UsernamePasswordAuthenticationToken),郵箱+密碼,手機(jī)號(hào)碼+密碼登錄則對(duì)應(yīng)了三個(gè)AuthenticationProvider。其中有一個(gè)重要的實(shí)現(xiàn)類(lèi)是ProviderManager
8、DaoAuthenticationProvider
AuthenticationProvider最最最常用的一個(gè)實(shí)現(xiàn)便是DaoAuthenticationProvider。顧名思義,Dao正是數(shù)據(jù)訪問(wèn)層的縮寫(xiě),也暗示了這個(gè)身份認(rèn)證器的實(shí)現(xiàn)思路。主要作用:它獲取用戶(hù)提交的用戶(hù)名和密碼,比對(duì)其正確性,如果正確,返回一個(gè)數(shù)據(jù)庫(kù)中的用戶(hù)信息(假設(shè)用戶(hù)信息被保存在數(shù)據(jù)庫(kù)中)。
三、比較一下shiro與SpringSecurity
Shiro 的優(yōu)點(diǎn):
首先Shiro較之 Spring Security,Shiro在保持強(qiáng)大功能的同時(shí),還在簡(jiǎn)單性和靈活性方面擁有巨大優(yōu)勢(shì)。
Shiro是一個(gè)強(qiáng)大而靈活的開(kāi)源安全框架,能夠非常清晰的處理認(rèn)證、授權(quán)、管理會(huì)話(huà)以及密碼加密。如下是它所具有的特點(diǎn):
- 易于理解的 Java Security API;
- 簡(jiǎn)單的身份認(rèn)證(登錄),支持多種數(shù)據(jù)源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
- 對(duì)角色的簡(jiǎn)單的簽權(quán)(訪問(wèn)控制),支持細(xì)粒度的簽權(quán);
- 支持一級(jí)緩存,以提升應(yīng)用程序的性能;
- 內(nèi)置的基于 POJO 企業(yè)會(huì)話(huà)管理,適用于 Web 以及非 Web 的環(huán)境;
- 異構(gòu)客戶(hù)端會(huì)話(huà)訪問(wèn);
- 非常簡(jiǎn)單的加密 API;
- 不跟任何的框架或者容器捆綁,可以獨(dú)立運(yùn)行。
- Shiro則是一個(gè)輕量級(jí)的安全管理框架,Shiro概念簡(jiǎn)單、配置簡(jiǎn)單,Shiro功能簡(jiǎn)單, Shiro 比 Spring security 更容易使用,實(shí)現(xiàn)和最深入的理解
- Apache Shiro在Spring Security處理密碼學(xué)方面有一個(gè)額外的模塊
- Shiro 是Apache 下的項(xiàng)目比較可靠,且不跟任何的框架或者容器綁定,可以獨(dú)立于任何項(xiàng)目運(yùn)行
- 從使用情況上看,二者都在逐步提高使用量。shiro的使用量一直高于spring security. shiro可以用于非web環(huán)境,不跟任何框架或容器綁定,獨(dú)立運(yùn)行shiro入門(mén)更加容易,使用起來(lái)也非常簡(jiǎn)單,這也是造成shiro的使用量一直高于Spring Security的主要原因
spring security 優(yōu)點(diǎn)
? Spring Security是一個(gè)重量級(jí)的安全管理框架,Spring Security更加知名的唯一原因是因?yàn)槠放泼Q(chēng), Spring Security功能強(qiáng)大,Spring Security有更好的社區(qū)支持
由于Spring Boot官方提供了大量的非常方便的開(kāi)箱即用的 Starter,包括 Spring Security 的 Starter,使得在SpringBoot 中使用 Spring Security 變得更加容易,甚至只需要添加一個(gè)依賴(lài) 就可以保護(hù)所有接口,所以如果是SpringBoot項(xiàng)目,一般選擇Spring Security。當(dāng)然這只是 一個(gè)建議的組合,單純從技術(shù)上來(lái)說(shuō),無(wú)論怎么組合,都是沒(méi)有問(wèn)題的。在沒(méi)有Spring Boot之前,Spring Security的大部分配置要通過(guò)XML實(shí)現(xiàn),配置還是還是非常復(fù)雜的。但是有了 Spring Boot之后,這一情況已經(jīng)得到顯著改善。
Spring Security之所以看上去比shiro更復(fù)雜,其實(shí)是因?yàn)樗肓艘恍┎怀S玫母拍钆c規(guī)則。大家應(yīng)該都知道2/8法則,這在Spring Security里面體現(xiàn)的特別明顯,如果你只學(xué)Spring Security最重要的那20%,這20%的復(fù)雜度和shiro基本是一致的。也就是說(shuō),不重要的那80%,恰恰是Spring Security比shiro的“復(fù)雜度”。
也就是說(shuō),你把Spring Security最重要的那20%熟練掌握,二者的入門(mén)門(mén)檻、復(fù)雜度其實(shí)是差不太多的。
Spring Security依托于Spring龐大的社區(qū)支持,這點(diǎn)自不必多說(shuō)。shiro屬于apache社區(qū),因?yàn)樗膹V泛使用,文檔也非常的全面。二者從社區(qū)支持來(lái)看,幾乎不相上下。
但是從社區(qū)發(fā)展的角度看,Spring Security明顯更占優(yōu)勢(shì),隨著Spring Cloud、Spring Boot、Spring Social的長(zhǎng)足進(jìn)步,這種優(yōu)勢(shì)會(huì)越來(lái)越大。因?yàn)镾pring Security畢竟是Spring的親兒子,Spring Security未來(lái)在于Spring系列框架集成的時(shí)候一定會(huì)有更好的融合性,前瞻性、兼容性!這也是為什么我們要學(xué)Spring Security的主要原因!
Spring Security因?yàn)樗膹?fù)雜,所以從功能的豐富性的角度更勝一籌。其中比較典型的如:
Spring Security 默認(rèn)含有對(duì)OAuth2.0的支持,與Spring Social一起使用完成社交媒體登錄也比較方便,shiro 則需要自己手動(dòng)實(shí)現(xiàn),而且 spring security 的權(quán)限細(xì)粒度更高,除了不能脫離Spring,shiro的功能它都有。而且Spring Security對(duì)OpenID也有支持,Shiro則需要自己手動(dòng)寫(xiě)代碼實(shí)現(xiàn)。
Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架。它是用于保護(hù)基于Spring的應(yīng)用程序的實(shí)際標(biāo)準(zhǔn)。Spring Security致力于為Java應(yīng)用程序提供身份驗(yàn)證和授權(quán)。與所有Spring項(xiàng)目一樣,Spring Security的真正強(qiáng)大之處在于可以輕松擴(kuò)展以滿(mǎn)足自定義要求
Spring Security在網(wǎng)絡(luò)安全的方面下的功夫更多,如 會(huì)話(huà)固定攻擊 和 CSRF 攻擊 等等,spring security 做了大量防御機(jī)制,這是shiro所不具備的。
四、總結(jié)
目前在java web應(yīng)用安全框架中,使用Apache Shiro的人較多,因?yàn)樗喈?dāng)簡(jiǎn)單,對(duì)比Spring Security,可能沒(méi)有Spring Security做的功能強(qiáng)大,但是在實(shí)際工作時(shí)可能并不需要那么復(fù)雜的東西,所以使用小而簡(jiǎn)單的Shiro就足夠了。對(duì)于它倆到底哪個(gè)好,這個(gè)不必糾結(jié),能更簡(jiǎn)單的解決項(xiàng)目問(wèn)題就好了。
與shiro形成直接競(jìng)爭(zhēng)的就是spring Security,二者在核心功能上幾乎差不多,但從使用的角度各有優(yōu)缺點(diǎn)。
我認(rèn)為:沒(méi)有最好的,只有最合適的。
ing Security,可能沒(méi)有Spring Security做的功能強(qiáng)大,但是在實(shí)際工作時(shí)可能并不需要那么復(fù)雜的東西,所以使用小而簡(jiǎn)單的Shiro就足夠了。
對(duì)于它倆到底哪個(gè)好,這個(gè)不必糾結(jié),能更簡(jiǎn)單的解決項(xiàng)目問(wèn)題就好了。
與shiro形成直接競(jìng)爭(zhēng)的就是spring Security,二者在核心功能上幾乎差不多,但從使用的角度各有優(yōu)缺點(diǎn)。
我認(rèn)為:沒(méi)有最好的,只有最合適的。
如果你只是想實(shí)現(xiàn)一個(gè)簡(jiǎn)單的web應(yīng)用,shiro更加的輕量級(jí),學(xué)習(xí)成本也更低。
如果您正在開(kāi)發(fā)一個(gè)分布式的、微服務(wù)的、或者與Spring Cloud系列框架深度集成的項(xiàng)目,還是建議您使用Spring Security。
到此這篇關(guān)于Java中security與shiro的區(qū)別詳解的文章就介紹到這了,更多相關(guān)security與shiro的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文詳解Spring中的HttpMessageNotReadableException異常處理
這篇文章主要為大家詳細(xì)介紹了Spring中的HttpMessageNotReadableException異常,分析其產(chǎn)生的原因并通過(guò)實(shí)際代碼示例展示如何有效地捕獲和處理這一異常,感興趣的可以了解下2025-02-02javaweb購(gòu)物車(chē)案列學(xué)習(xí)開(kāi)發(fā)
這篇文章主要為大家詳細(xì)介紹了javaweb購(gòu)物車(chē)案列學(xué)習(xí)開(kāi)發(fā)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05看動(dòng)畫(huà)學(xué)算法之Java實(shí)現(xiàn)doublyLinkedList
這篇文章主要介紹Java實(shí)現(xiàn)doublyLinkedList,LinkedList:doublyLinkedList相對(duì)比較復(fù)雜,今天就來(lái)簡(jiǎn)單學(xué)習(xí)一下doublyLinkedList的基本操作和概,感興趣的小伙伴可以參考下面具體文章內(nèi)容2021-10-10Java中String類(lèi)startsWith方法詳解
這篇文章主要給大家介紹了關(guān)于Java中String類(lèi)startsWith方法的相關(guān)資料,startsWith() 方法用于檢測(cè)字符串是否以指定的前綴開(kāi)始,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05IDEA實(shí)現(xiàn)Maven項(xiàng)目創(chuàng)建并連接Tomcat方式
Maven是一款由Apache開(kāi)發(fā)的項(xiàng)目管理工具,主要用于Java項(xiàng)目的構(gòu)建和依賴(lài)管理,它通過(guò)pom.xml文件自動(dòng)管理項(xiàng)目依賴(lài)的jar包,簡(jiǎn)化了項(xiàng)目構(gòu)建過(guò)程,Maven支持項(xiàng)目從編寫(xiě)源代碼到編譯、測(cè)試、打包、部署的全過(guò)程管理,其依賴(lài)管理功能免去了手動(dòng)添加jar包的麻煩2024-10-10Java使用設(shè)計(jì)模式中的工廠方法模式實(shí)例解析
當(dāng)系統(tǒng)準(zhǔn)備為用戶(hù)提供某個(gè)類(lèi)的子類(lèi)的實(shí)例,又不想讓用戶(hù)代碼和該子類(lèi)形成耦合時(shí),就可以使用工廠方法模式來(lái)設(shè)計(jì)系統(tǒng).工廠方法模式的關(guān)鍵是在一個(gè)接口或抽象類(lèi)中定義一個(gè)抽象方法,下面我們會(huì)具體介紹Java使用設(shè)計(jì)模式中的工廠方法模式實(shí)例解析.2016-05-05