茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671963 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_60D_00058.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

爪哇咖啡屋 : [轉貼]Apache Shiro 實戰之 Shiro 簡介

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Apache Shiro 實戰之 Shiro 簡介

JeeSite4.0功能權限 / 基礎 (Apache Shiro)

作者:@JeeGit 長春叭哥

更新日期:2018-10-27

一、Shiro簡介

Apache Shiro™是一個功能強大且易於使用的Java安全框架,可執行身份驗證授權加密會話管理。藉助Shiro易於理解的API,您可以快速輕鬆地保護任何應用程式 - 從最小的移動應用程式到最大的Web和企業應用程式。

1.1官方地址

1.2 10分鐘快速入門教程

Shiro可以在任何環境中運行,從最簡單的命令行應用程式到最大的企業Web和集群應用程式,但是我們將在這個QuickStart的簡單`main`方法中使用最簡單的示例,這樣您就可以感受到API。

1.3 Apache Shiro集成

將Apache Shiro集成到基於Spring的應用程式中。

將Apache Shiro集成到基於Guice的應用程式中。

CAS SSO伺服器使用Jasig CAS SSO伺服器保護您的WebApp。

1.4 Apache Shiro功能概述

Apache Shiro旨在成為最全面,但也是最容易使用的Java安全框架。以下是一些更精細的框架概述:

最容易理解Java Security API的地方。類和接口名稱直觀且有意義。任何東西都是可插拔的,但一切都有很好的默認值。

支持跨一個或多個可插拔數據源(LDAP,JDBC,ActiveDirectory等)的身份驗證('登錄')。

基於角色或細粒度權限執行授權("訪問控制"),也使用可插拔數據源。

一流的緩存支持,增強了應用程式性能。

內置基於POJO的企業會話管理。在Web和非Web環境中或在需要單點登錄(SSO)或群集或分布式會話的任何環境中使用。

異構客戶端會話訪問。您不再被迫僅使用httpSession或有狀態會話Bean,這通常會不必要地將應用程式綁定到特定環境。無論部署環境如何,Flash applet,C#應用程式,Java Web Start和Web應用程式等現在都可以共享會話狀態。

簡單的單點登錄(SSO)支持搭載上述企業會話管理。如果會話跨多個應用程式聯合,則也可以共享用戶的身份驗證狀態。登錄到任何應用程式,其他人都識別登錄。

使用最簡單的可用密碼學 API 保護數據,為您提供超出Java默認提供的密碼和哈希值的功能和簡單性。

一個非常強大但低配置的 Web框架,可以保護任何URL或資源,自動處理登錄和註銷,執行Remember Me服務等。

極低數量的必需依賴項。獨立配置只需要slf4j-api.jar和slf4j的綁定.jars之一。Web配置還需要commons-beanutils-core.jar。可以在需要時添加基於功能的依賴項(Ehcache緩存,基於Quartz的會話驗證,Spring依賴項注入等)。

二、Shiro主要組件的特定功能

2.1身份驗證 authentication

Apache Shiro身份驗證功能

身份驗證是身份驗證的過程 - 您試圖驗證用戶是否是他們所說的人。為此,用戶需要提供系統理解和信任的某種身份證明。

Shiro框架旨在使身份驗證儘可能乾淨和直觀,同時提供豐富的功能。以下是Shiro身份驗證功能的一個亮點。

2.1.1基於主題

Subject Based - 您在Shiro中執行的幾乎所有操作都基於當前正在執行的用戶,稱為主題。您可以輕鬆地在代碼中的任何位置檢索主題。這使您更容易理解並在您的應用程式中使用Shiro。

2.1.2單一方法調用

Single Method call - 身份驗證過程是單個方法調用。只需要一個方法調用就可以簡化API並簡化應用程式代碼,從而節省您的時間和精力。

2.1.3豐富的異常層次結構


Rich Exception Hierarchy - Shiro提供了豐富的異常層次結構,以提供有關登錄失敗原因的詳細說明。層次結構可以幫助您更輕鬆地診斷與身份驗證相關的代碼錯誤或客戶服務問題。此外,豐富性可以幫助您在需要時創建更複雜的身份驗證功能。

2.1.4內置'Remember Me'

Remember Me' built in - Shiro API中的標準功能是能夠在用戶返回應用程式時記住他們。您可以通過最少的開發工作為他們提供更好的用戶體驗。

2.1.5可插拔數據源

Pluggable data sources - Shiro使用可插拔數據訪問對象(DAO)(稱為Realms)連接到LDAP和Active Directory等安全數據源。為了幫助您避免自己構建和維護集成,Shiro為LDAP,Active Directory和JDBC等流行數據源提供了開箱即用的領域。如果需要,您還可以創建自己的領域,以支持基本領域中未包含的特定功能。

2.1.6使用一個或多個領域登錄

Login with one or more realms - 使用Shiro,您可以輕鬆地針對一個或多個領域對用戶進行身份驗證,並返回其身份的統一視圖。此外,您可以使用Shiro的身份驗證策略概念自定義身份驗證過程。可以在配置文件中設置策略,因此更改不需要修改原始碼 - 從而降低了複雜性和維護工作量。

2.2授權 authorization

Apache Shiro授權功能

授權(也稱為訪問控制)是確定應用程式中資源的訪問權限的過程。換句話說,確定"誰有權訪問什麼。"授權用於回答安全問題,例如"允許用戶編輯帳戶","此用戶是否允許查看此網頁","該用戶是否可以訪問"到這個按鈕?"這些都決定了用戶可以訪問的內容,因此都代表授權檢查。

授權是任何應用程式的關鍵元素,但它很快就會變得非常複雜。Shiro的目標是消除授權的大部分複雜性,以便您可以更輕鬆地構建安全的軟體。以下是Shiro授權功能的一個亮點。

2.2.1基於主題


Subject-based - 您在Shiro中執行的幾乎所有操作都基於當前正在執行的用戶,稱為主題。您可以輕鬆訪問主題,檢索主題並在代碼中的任何位置檢查其角色,權限或其他相關屬性。這使您更容易理解並在您的應用程式中使用Shiro。

2.2.2基於角色或權限的檢查

Checks based on roles or permissions - 由於授權的複雜性在應用程式之間存在很大差異,因此Shiro旨在實現靈活性,根據您的項目需求支持基於角色的安全性和基於權限的安全性。

2.2.3強大而直觀的權限語法

Powerful and intuitive permission syntax - 作為一種選擇,Shiro提供了一種開箱即用的權限語法,稱為通配符權限,可幫助您對應用程式可能具有的細粒度訪問策略進行建模。通過使用Shiro的通配符權限,您將獲得易於處理和人類可讀的語法。此外,您不必花費時間和精力創建自己的方法來表示訪問策略。

2.2.4多個強制執行選項

Multiple enforcement options - Shiro中的授權檢查可以通過代碼內檢查,JDK 1.5注釋,AOP和JSP / GSP Taglib來完成。Shiro的目標是讓您根據自己的喜好和項目需求選擇使用您認為最佳的選項。

2.2.5強大的緩存支持

Strong caching support- 任何現代開源和/或企業緩存產品都可以插入Shiro,以提供快速有效的用戶體驗。對於授權,緩存對於較大環境中的性能或使用後端安全數據源的更複雜策略至關重要。

2.2.6可插拔數據源

Pluggable data sources - Shiro使用可插拔數據訪問對象(稱為Realms)連接到保存訪問控制信息的安全數據源,如LDAP伺服器或關係資料庫。為了幫助您避免自己構建和維護集成,Shiro為LDAP,Active Directory和JDBC等流行數據源提供了開箱即用的領域。如果需要,您還可以創建自己的領域,以支持基本領域中未包含的特定功能。

2.2.7支持任何數據模型


Supports any data model - Shiro可以支持訪問控制的任何數據模型 - 它不會強制模型在您身上。您的領域實現最終決定您的權限和角色如何組合在一起以及是否向Shiro返回"是"或"否"答案。此功能允許您以您選擇的方式構建應用程式,Shiro將為您提供支持。

2.3會話管理 session-management

會話是您的用戶在使用您的應用程式時攜帶一段時間的數據桶。傳統上,會話專用於Web或EJB環境。不再!Shiro支持任何應用程式環境的會話。此外,Shiro還提供了許多其他強大的功能來幫助您管理會話。

2.3.1基於POJO / J2SE(IoC友好)

POJO/J2SE based (IoC friendly) - Shiro中的所有內容(包括會話和會話管理的所有方面)都是基於接口的,並使用POJO實現。這允許您使用任何與JavaBeans兼容的配置格式(如JSON,YAML,Spring XML或類似機制)輕鬆配置所有會話組件。您還可以根據需要輕鬆擴展Shiro的組件或編寫自己的組件,以完全自定義會話管理功能。

2.3.2會話存儲

Session Storage - 由於Shiro的Session對象是基於POJO的,因此會話數據可以輕鬆存儲在任意數量的數據源中。這允許您準確自定義應用程式的會話數據所在的位置 - 例如,文件系統,企業緩存,關係資料庫或專有數據存儲。

2.3.3輕鬆而強大的群集

Easy and Powerful Clustering - 使用任何易於使用的網絡緩存產品(如Ehcache,Coherence,GigaSpaces等),可以輕鬆地對Shiro的會話進行群集。人。這意味著您可以為Shiro配置一次且僅一次的會話群集,無論您部署到哪個Web容器,您的會話都將以相同的方式進行群集。無需特定於容器的配置!

2.3.4異構客戶端訪問

Heterogeneous Client Access - 與EJB或Web會話不同,Shiro會話可以通過各種客戶端技術"共享"。例如,桌面應用程式可以"看到"並"共享"同一用戶在伺服器端Web應用程式中使用的相同物理會話。我們不知道Shiro以外的任何框架都可以支持這一點。

2.3.5事件偵聽器

Event listeners - 事件偵聽器允許您在會話的生命周期內偵聽生命周期事件。您可以偵聽這些事件並對它們做出反應以獲取自定義應用程式行為 - 例如,在會話過期時更新用戶記錄。

2.3.6主機地址保留

Host address retention – Shiro會話保留啟動會話的主機的IP位址。這允許您確定用戶所在的位置並做出相應的反應(主要用於IP關聯是確定性的Intranet環境)。

2.3.6不活動/到期支持

Inactivity/expiration support – 會話由於預期的不活動而到期,但是touch()如果需要,可以通過一種方法延長它們以保持它們"活著"。這在用戶可能正在使用桌面應用程式的Rich Internet Application(RIA)環境中很有用,但可能無法定期與伺服器通信,但伺服器會話不應過期。

2.3.7透明的Web使用

Transparent web use - Shiro的Web支持實現了HttpSession界面及其所有相關的API。這意味著您可以在現有Web應用程式中使用Shiro會話,而無需更改任何現有Web代碼。

2.3.8可以用於SSO

Can be used for SSO - 因為Shiro會話是基於POJO的,所以它們很容易存儲在任何數據源中,並且如果需要,它們可以跨應用程式"共享"。這可用於提供簡單的登錄體驗,因為共享會話可以保留身份驗證狀態。

2.4加密Cryptography

Apache Shiro密碼學特性

密碼術是通過隱藏信息或將其轉換為無意義來保護信息免受不良訪問的做法,因此沒有其他人可以閱讀它。Shiro專注於密碼學的兩個核心要素:使用公鑰或私鑰加密數據的密碼,以及對密碼等數據進行不可逆加密的哈希(也就是消息摘要)。

Shiro Cryptography的主要目標是採用傳統上非常複雜的領域,並在提供強大的密碼學功能的同時使其他人輕鬆實現。

2.4.1簡潔的特點

2.4.1.1接口驅動,基於POJO


Interface-driven, POJO based -所有Shiro的API都是基於接口的,並作為POJO實現。這使您可以使用JavaBeans兼容格式(如JSON,YAML,Spring XML等)輕鬆配置Shiro Cryptography組件。您還可以根據需要覆蓋或自定義Shiro,利用其API來節省您的時間和精力。

2.4.1.2JCE上的簡化包裝

Simplified wrapper over JCE-除非您是加密專家,否則Java加密擴展(JCE)可能很複雜且難以使用。Shiro的Cryptography API更易於理解和使用,並且它們極大地簡化了JCE概念。所以現在即使是Cryptography新手也可以在幾分鐘而不是幾小時或幾天內找到他們需要的東西。並且您不會犧牲任何功能,因為如果您需要它們仍然可以訪問更複雜的JCE選項。

2.4.1.3 "Object Orientifies"加密概念

"Object Orientifies" cryptography concepts -JDK / JCE的密碼和消息摘要(Hash)類是抽象類,非常令人困惑,要求您使用帶有類型不安全字符串參數的obtuse工廠方法來獲取要使用的實例。Shiro'Object Orientifies'的密碼和哈希,基於乾淨的對象層次結構,允許您通過簡單的實例化來使用它們。

2.4.1.4運行時異常

Runtime Exceptions -與Shiro中的其他任何地方一樣,所有加密異常都是RuntimeExceptions。您可以根據需要決定是否捕獲異常。

2.4.2密碼功能

2.4.2.1OO層次

OO Hierarchy - -不同的是JCE,四郎密碼申述追蹤與他們的數學概念,一個面向對象的類層次結構:AbstractSymmetricCipherService,DefaultBlockCipherService,AesCipherService等,這使您可以輕鬆覆蓋現有的類,並根據需要擴展功能。

2.4.2.2隻是實例化一個類


Just instantiate a class - 與使用String令牌參數的JCE令人困惑的工廠方法不同,使用2.4.2.3Shiro Ciphers要容易得多

More secure default settings - 只需實例化一個類,根據需要使用JavaBeans屬性對其進行配置,並根據需要使用它。例如,new AesCipherService()。

更安全的默認設置 - JCE Cipher實例採用"最小公分母"默認值,不會自動啟用更安全的選項。Shiro將自動啟用更安全的選項,以確保您的數據在默認情況下是安全的,幫助您防止意外的安全漏洞。

2.4.3哈希功能

2.4.3.1默認接口實現

Default interface implementations - Shiro提供了開箱即用的默認Hash(JDK中的消息摘要)實現,例如MD5,SHA1,SHA-256等。這提供了一種類型安全的構造方法(例如new Md5Hash(data)),而不是強制在JDK中使用類型不安全的字符串工廠方法。

2.4.3.2內置十六進位和Base64的轉換

Built-in Hex and Base64 conversion -四郎哈希實例可以經由他們的自動提供散列數據的十六進位和Base64編碼toHex()和toBase64()方法。所以現在你不需要弄清楚如何正確編碼數據。

2.4.3.2內置Salt和重複散列支持

Built-in Salt and repeated hashing support - 在散列數據時,Salts和重複散列疊代是非常有價值的工具,特別是在保護用戶密碼時。Shiro的Hash實現支持鹽和多個哈希疊代開箱即用,因此您無需在任何需要的地方重複此邏輯。

三、Spring Security

3.1官方地址

https://spring.io/projects/spring-security

Spring Security以前叫做acegi,後成為Spring的一個子項目,也是目前最為流行的一個安全權限管理框架。


Spring Security關注的重點是為企業應用安全層提供服務,在企業級軟體開發過程中業務問題領域存在著各式各樣的需求。銀行系統跟電子商務應用就有很大的不同。電子商務系統與企業銷售自動化工具又有很大不同。這些客戶化需求讓應用安全顯得有趣,富有挑戰性而且物有所值。Spring Security為基於J2EE的企業應用軟體提供了一套全面的安全解決方案。

四、Apache Shiro與Spring Security 對比

[國外]https://blog.novatec-gmbh.de/java-ee-security-framework-comparison/

[國內]

(1) Spring 社區當下更為活躍,Srping生態圈的解決方案或者第三方解決方案更全面。

(2) Spring Security除了不能脫離Spring,shiro的功能它都有。而且Spring Security對Oauth、OpenID也有支持,Shiro則需要自己手動實現。Spring Security官方的宣傳是權限細粒度更高(大部分國內網友+國外網友+小編還未發現高在哪裡)。

(3)Apache Shiro 更容易上手,更容易理解。

(4) SpringSecurity 安全性更勝一籌,但是學習與使用成本更高。

(5)個人認為現階段需求,權限的操作粒度能控制在路徑及按鈕上,數據粒度通過sql實現。Shrio簡單夠用。

(6) OAuth,OpenID 站點間統一登錄功能,現租戶與各個產品間單點登錄已經通過cookies實現,所以Spring Security的這兩個功能可以不考慮。


很多網友有這樣的評價:

SpringSide網站的權限也是用Shrio做的。SpringSide是以Spring Framework為核心的,Pragmatic風格的JavaEE應用參考示例,是JavaEE世界中的主流技術選型,最佳實踐的總結與演示。

這個有點誤導大家,實際上,SpringSide 與JeeSite、Jfinal類似,都屬於國產開源框架,並非是由Spring官方出品。



原文出處:Apache Shiro實戰之Shiro簡介 Apache Shiro vs Spring Security - 每日頭條
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Apache shiro 的簡單介紹與使用教程

Apache shiro的簡單介紹與使用教程(與spring整合使用)

apache shiro框架簡介

  Apache Shiro是一個強大而靈活的開源安全框架,它能夠乾淨利落地處理身份認證,授權,企業會話管理和加密。現在,使用Apache Shiro的人越來越多,因為它相當簡單,相比比Spring Security,Shiro可能沒有Spring Security那麼多強大的功能,但是在實際工作時可能並不需要那麼複雜的東西,所以使用簡單的Shiro就足夠了。

  以下是你可以用 Apache Shiro所做的事情:

  Shiro的4大核心部分——身份驗證,授權,會話管理和加密

     Authentication:身份驗證,簡稱“登入”。

     Authorization:授權,給使用者分配角色或者許可權資源

     Session Management:使用者session管理器,可以讓CS程式也使用session來控制許可權

     Cryptography:把JDK中複雜的密碼加密方式進行封裝。

  除了以上功能,shiro還提供很多擴充套件   

  Web Support:主要針對web應用提供一些常用功能。

  Caching:快取可以使應用程式執行更有效率。

  Concurrency:多執行緒相關功能。

  Testing:幫助我們進行測試相關功能

  Run As:一個允許使用者假設為另一個使用者身份(如果允許)的功能,有時候在管理指令碼很有用。

  Remember Me:記住使用者身份,提供類似購物車功能。

  shiro框架認證流程

  Application Code:應用程式程式碼,由開發人員負責開發的


  Subject:框架提供的介面,是與程式進行互動的物件,可以是人也可以是服務或者其他,通常就理解為使用者。所有Subject 例項都必須繫結到一個SecurityManager上。我們與一個 Subject 互動,執行時shiro會自動轉化為與 SecurityManager互動的特定 subject的互動。

  SecurityManager:框架提供的介面,是 Shiro的核心,代表安全管理器物件。初始化時協調各個模組執行。然而,一旦 SecurityManager協調完畢,SecurityManager 會被單獨留下,且我們只需要去操作Subject即可,無需操作SecurityManager 。 但是我們得知道,當我們正與一個 Subject 進行互動時,實質上是 SecurityManager在處理 Subject 安全操作。

  Realm:可以開發人員編寫,框架也提供一些。Realms在 Shiro中作為應用程式和安全資料之間的“橋樑”或“聯結器”。他獲取安全資料來判斷subject是否能夠登入,subject擁有什麼許可權。他有點類似DAO。在配置realms時,需要至少一個realm。而且Shiro提供了一些常用的 Realms來連線資料來源,如LDAP資料來源的JndiLdapRealm,JDBC資料來源的JdbcRealm,ini檔案資料來源的IniRealm,properties檔案資料來源的PropertiesRealm,等等。我們也可以插入自己的 Realm實現來代表自定義的資料來源。 像其他元件一樣,Realms也是由SecurityManager控制。

  更詳細的圖

  下面就開始shiro與SSM工程的整合使用

  下載地址: http://shiro.apache.org/download.html

  下載下來這兩個個檔案,一個jar包,一個原始碼檔案

  首先,第一步,將jar包匯入到工程中


  然後,第二步,在web.xml中配置spring框架提供的用於整合shiro框架的過濾器(一定要放到springmvc或struts框架過濾器的前面,為了保險起見,放到最上面就好了)



<!--配置過濾器,用於整合Shiro-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

  第三步,在spring配置檔案中配置bean,id為shiroFilter



<!-- 配置shiro框架的過濾器工廠bean -->
<bean id="shiroFilter" >
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/index.jsp"/>
<property name="successUrl" value=""/>
<property name="unauthorizedUrl" value="/noPrivilegeUI.jsp"/>
<!-- 指定URL級別攔截策略 -->
<property name="filterChainDefinitions">
<value>
/script/** = anon
  /style/** = anon
  /index.jsp* = anon
  /noPrivilegeUI.jsp* = anon
  /user/login = anon
       /role/findAllRoleList = perms["角色管理"]
  /** = authc
</value>
</property>
</bean>

  securityManager:這個屬性是必須的。

  loginUrl :沒有登入的使用者請求需要登入的頁面時自動跳轉到登入頁面,不是必須的屬性,不輸入地址的話會自動尋找專案web專案的根目錄下的”/login.jsp”頁面。

  successUrl :登入成功預設跳轉頁面,可以不配置,不配置則跳轉至”/”。如果登陸前點選的一個需要登入的頁面,則在登入自動跳轉到那個需要登入的頁面。不跳轉到此。

  unauthorizedUrl :沒有許可權預設跳轉的頁面。

  anon: 例子/admins/** = anon 沒有引數,表示可以匿名使用(需要認證(登入))。

  authc : 例如/admins/user/** = authc 表示需要認證(登入)才能使用,沒有引數

  roles:例子/admins/user/** = roles[admin], 引數可以寫多個,多個時必須加上引號,並且引數之間用逗號分割,當有多個引數時,例如admins/user/** = roles[“admin,guest”], 每個引數通過才算通過,相當於hasAllRoles()方法。

  perms:例子/admins/user/** = perms[user:add:*], 引數可以寫多個,多個時必須加上引號,並且引數之間用逗號分割,例如/admins/user/** = perms[“user:add:*,user:modify:*”],當有多個引數時必須每個引數都通過才通過,想當於  isPermitedAll()方法。

  Rest:例子/admins/user/** = rest[user];根據請求的方法,相當於/admins/user/** = perms[user:method] ;其中method為post,get,delete等。


  port:例子/admins/user/** = port[8081]; 當請求的url的埠不是8081是跳轉到schemal://serverName:8081?queryString,其中schmal是協議http或https等,serverName是你訪問的host,8081是url配置裡port的埠,queryString

是你訪問的url裡的?後面的引數。

  authcBasic:例如/admins/user/** = authcBasic; 沒有參數列示httpBasic認證

  ssl:例子/admins/user/** = ssl;沒有引數,表示安全的url請求,協議為https

  user:例如/admins/user/** = user; 沒有參數列示必須存在使用者,當登入操作時不做檢查

  注:anon,authcBasic,auchc,user是認證過濾器,

    perms,roles,ssl,rest,port是授權過濾器

  第四步:配置安全管理器



<!-- 配置安全管理器 -->
<bean id="securityManager" />

  第五步:寫一個login方法,使用shiro提供的方式進行認證操作

  這是我之前的login方法,以這種方法,shiro是不知道登入驗證通過了的,一直不通過,所以我們要以shiro提供的認證操作方式進行登入操作



/**
* 登入
*/
@RequestMapping("/login")
public String login(User user, HttpServletRequest request, Model model){
  HttpSession session = request.getSession();
  User newUser = userService.login(user);
  if(newUser != null){
    session.setAttribute("loginUser",newUser);
    return "home/home";
  }
  model.addAttribute("errorMessage","使用者名稱或者密碼不正確!");
  return "forward:/index.jsp";
}

   修改後的login方法



/**
* 使用Shiro框架提供的方式進行認證登入
*/
@RequestMapping("/login")
public String login(User user, HttpServletRequest request, Model model){
  HttpSession session = request.getSession();
//使用Shiro框架提供的方式進行認證
Subject subject = SecurityUtils.getSubject(); //獲得當前登入使用者物件,現在狀態為 “未認證”
//使用者名稱密碼令牌
AuthenticationToken token = new UsernamePasswordToken(user.getLoginName(), MD5Utils.md5(user.getPassword()));
try{
  subject.login(token); //執行你自定義的Realm
  User user1 = (User) subject.getPrincipal();
  session.setAttribute("loginUser",user1);
  return "home/home";
}catch(UnknownAccountException e){
  e.printStackTrace();
  model.addAttribute("errorMessage","此使用者名稱不存在!");
}catch(IncorrectCredentialsException e){
  e.printStackTrace();
  model.addAttribute("errorMessage","密碼不正確!");
}catch(Exception e){
  e.printStackTrace();
}
return "forward:/index.jsp";
}

  第六步:自定義realm,並注入給安全管理器 

  建立一個UserRealm類,繼承AuthorizingRealm這個類 



public class UserRealm extends AuthorizingRealm{
@Autowired
private UserDao userDao;
   //認證方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("realm中的認證方法執行了。。。。");
UsernamePasswordToken myToken = (UsernamePasswordToken) token;
String loginName = myToken.getUsername();
//根據使用者名稱查詢資料庫中的使用者,這個方法是自己寫的
User user = userDao.findUserByLoginName(loginName);
if(user == null){
//使用者名稱不存在
return null;
}
//如果能查詢到,再由框架比對資料庫中查詢到的密碼和頁面提交的密碼是否一致
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return info;
}
   //授權方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
}

  將自定義realm注入給安全管理器



<!-- 配置安全管理器 -->
<bean id="securityManager" >
<!-- 注入realm -->
<property name="realm" ref="userRealm"/>
</bean>
<!-- 註冊自定義realm -->
<bean id="userRealm" />

  到這裡程式就可以正常執行了,登入後進入首頁

  但是點選角色管理,會進入沒有許可權的頁面

  這是因為我在spring配置檔案中配置了   /role/findAllRoleList = perms[“角色管理”],而我還沒有給當前使用者授權,所以當前使用者沒有許可權訪問此路徑

  所以要給該使用者授權,在UserRealm類中,編寫授權方法



//授權方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
User user = (User) principals.getPrimaryPrincipal();
for (Role role : user.getRoles()){
for (Privilege privilege : role.getPrivileges()){
info.addStringPermission(privilege.getName());
}
}
return info;
}

  這樣,就可以正常訪問了,這個授權方法是在訪問/role/findAllRoleList這個路徑時,shiro框架自動呼叫的

  我們之前進行許可權控制是在spring配置檔案中配置了   /role/findAllRoleList = perms[“角色管理”] ,現在介紹另一種方式,也是我比較喜歡的方式, 使用註解方式進行許可權控制

   使用shiro的方法註解方式許可權控制

  第一步:在springmvc配置檔案中開啟shiro註解支援(注意:springmvc框架,放到springmvc配置檔案中,struts放到spring配置檔案中) 



<!-- 保證實現了Shiro內部lifecycle函式的bean執行 -->
<bean id="lifecycleBeanPostProcessor" />
<!-- 開啟shiro框架註解支援 -->
<!-- 自動代理 -->
<bean id="defaultAdvisorAutoProxyCreator" >
<!-- value必須設定為true使用cglib方式為物件建立代理物件,
預設為false,設為false,就是使用JDK方式為物件建立代理物件,程式會出錯 -->
<property name="proxyTargetClass" value="true"/>
</bean>
<!-- 配置shiro框架提供的切面類,用於建立代理物件 -->
<bean />

  第二步:在Controller的方法上使用shiro註解—— @RequiresPermissions(“”) 執行這個方法必須有相應的許可權  



/**
* 查詢崗位列表
*/
@RequiresPermissions("角色列表") //執行這個方法必須有角色列表這個許可權
@RequestMapping("/findAllRoleList")
public String findAllRoleList(Model model){
List<Role> roleList = roleService.findAllRoleList();
model.addAttribute("roleList",roleList);
return "role/list";
}

  @RequiresAuthentication

    驗證使用者是否登入,等同於方法subject.isAuthenticated() 結果為true時。

  @ RequiresUser

    驗證使用者是否被記憶,user有兩種含義:

    一種是成功登入的(subject.isAuthenticated() 結果為true);

    另外一種是被記憶的( subject.isRemembered()結果為true)。

  @ RequiresGuest

    驗證是否是一個guest的請求,與@ RequiresUser完全相反。

           換言之,RequiresUser  == ! RequiresGuest 。

      此時subject.getPrincipal() 結果為null.

  @ RequiresRoles

    例如:



@RequiresRoles("aRoleName");
   void someMethod();

    如果subject中有aRoleName角色才可以訪問方法someMethod。如果沒有這個許可權則會丟擲異常AuthorizationException。

  @RequiresPermissions

    例如:



@RequiresPermissions( {"file:read", "write:aFile.txt"} )
   void someMethod();

    要求subject中必須同時含有file:read和write:aFile.txt的許可權才能執行方法someMethod()。否則丟擲異常AuthorizationException。

   註解方式的許可權控制就完成了,但這種方式沒有許可權時不會自動跳轉到沒有許可權的頁面,而是直接把異常拋到頁面了,所以我們要配置一個全域性的異常處理

  第三步:在springmvc配置檔案中,進行如下配置,配置全域性異常捕獲,當shiro框架丟擲許可權不足異常時,跳轉到許可權不足提示頁面



<!-- 全域性異常處理 -->
<bean >
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">redirect:/noPrivilegeUI.jsp</prop>
</props>
</property>
</bean>

  使用shiro提供的頁面標籤方式許可權控制

  最後,說一說shiro提供的頁面標籤  

  第一步:在jsp頁面中引入shiro的標籤庫



<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>

  第二步:使用shiro的標籤控制頁面元素展示

  這樣,一個shiro入門程式就完成了。

總結

以上所述是小編給大家介紹的Apache shiro的簡單介紹與使用教程(與spring整合使用),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對指令碼之家網站的支援!


原文出處: Apache shiro的簡單介紹與使用教程
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|