戒色詩: 二八佳人體似酥,腰間仗劍斬凡夫。雖然不見人頭落,暗裏教君骨髓枯。前端
關於Shiro 的教程,推薦你們看 張開濤前輩寫得 跟我學Shiro, 寫得很是好。數據庫
老蝴蝶寫得這個 Shiro 系列,側重於實際應用,因此太深奧的內容不進行講解,你們看張開濤前輩寫的Shiro 文章就好。apache
另,本系列shiro 內容會大量參考張開濤前輩的文章,謝謝!!!緩存
前面,咱們在控制權限,保障數據隱私和安全時,都是本身編寫的代碼程序進行相應的控制。安全
咱們本身前面實現的 權限驗證,操做複雜,功能簡單,複用率低, 一些常見的功能,如 單點登陸,記住我,密碼加密等,很難實現,還須要根據不一樣的框架寫不一樣的過濾器或者攔截器,本身手動配置靜態的和不須要認證的頁面url.多線程
咱們但願能有一個工具,就像 Quartz 實現做業調度同樣,實現權限的控制? 咱們只須要把用戶,角色,權限的數據交給這個工具,經過簡單的配置,這個工具就能自動幫咱們實現認證和受權的操做。架構
有這個工具,這個工具就是 Shiro.併發
Shiro 能夠幫咱們快速地實現 認證和受權的功能,保障系統地安全。框架
Shiro 是一個強大的 Java安全框架,愈來愈多的人使用它。適用於 JavaSE 和 JavaEE。maven
能夠進行 認證,受權,加密和會話管理 ,也支持Web,單點登陸,記住我等功能。
Shiro屬於Apache 組織下的項目,官網爲: http://shiro.apache.org/
咱們下載的是經典的 1.2.2 版本
在maven 中直接 引入 shiro-all 的依賴
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.2</version> </dependency>
相應的jar包爲:
在寫 shiro 的例子以前,咱們須要先了解關於Shiro 的一些概念。(概念摘錄於張開濤前輩的shiro文章)
Shiro 會咱們提供了這些功能。
功能模塊名 | 對應解釋 |
---|---|
Authentication | 身份認證(通俗講爲登陸),驗證用戶是不是合法的用戶 |
Authorization | 受權(通俗講爲權限驗證),驗證某個已經認證經過的用戶是否具備某個權限,用於判斷用戶是否能作某些事情 |
Session Manager | 會話管理。用戶登陸後就是一次會話,在沒有退出以前,它的全部的信息都會在會話裏面。會話能夠是 JavaSE環境,也能夠是Web環境 |
Cryptography | 加密,用於保護數據的安全性,如密碼加密,而不是明文存儲 |
Web Support | Web支持,用於集成到 Web環境 |
Caching | 緩存,用戶登陸以後,其用戶信息,擁有的角色和權限沒必要每次都去查,能夠提升效率,如ehcache緩存 |
Concurrency | 多線程併發驗證,即如在一個線程中開啓另外一個線程,就能把權限自動傳播過去 |
Testing | 提供測試支持 |
Run As | 容許一個用戶僞裝爲另外一個用戶(若是他們容許)的身份進行訪問 |
Remember Me | 記住我,即一次登陸後,下次再來的話,就不用從新登陸 |
經常使用的就是,身份認證 Authentication,受權 Authorization,加密 Cryptography和 記住我 Remember Me.
Shiro 的三大主體, Subject, SecurityManager, Realm 如何進行工做的。
名稱 | 對應解釋 |
---|---|
Subject | 主體,表明當前的"用戶",但這個用戶不必定指具體的人。 |
SecurityManager | 安全管理器,即全部與安全有關的操做都會與Security Manager 進行交互,它管理着全部的 Subject,是 Shiro的核心,負責與Realm 進行交互 |
Realm | 域,Shiro從域中獲取安全數據,至關於DataSource 數據源 |
補充: 咱們編寫的代碼裏面使用的是 Subject,即應用代碼直接交互的對象是 Subject. 全部的Subject 都會綁定到 SecurityManager上,全部的交互也都會委託給SecurityManager, 是一個門面,而Security Manager是實際的執行者。
Security Manager 至關於 SpringMVC的 DispatcherServlet 前端控制器,無處不在,功能強大。
Realm至關於數據源, SecurityManager要驗證用戶的身份,獲取用戶的權限,這個數據從哪兒獲取呢? 就是經過Realm 進行獲取。
總結: 應用代碼經過 Subject對象調用方法, 來進行認證和受權,而Subject 又委託SecurityManager處理(即真正幹活的是 SecurityManager)
須要給SecurityManager 注入Realm, 從而讓SecurityManager獲得合法的用戶信息和角色/權限數據。
注意,數據是咱們開發者提供的,Shiro 不維護數據,只查詢,不更新。
具體的功能組件
名稱 | 解釋 |
---|---|
Subject | 主體,能夠看到主體是任何能夠與應用交互的用戶 |
SecurityManager | 全部具體的交互都是經過它進行控制的,管理着全部的Subject |
Authenticator | 認證器,負責主體認證的,須要配置認證策略 Strategy |
Authrizer | 受權器,用來決定主體是否有權限進行相應的操做 |
Realm | 安全實體數據源,用於獲取數據 |
SessionManager | 會話管理,用於管理Session |
SessionDAO | 用於會話的CRUD |
CacheManager | 緩存管理,用於提升訪問的性能,常存儲用戶,角色,權限 |
Cryptography | 密碼模塊,用於加密用戶的密碼等隱私數據 |
身份認證,是在應用中誰能證實他就是他本人。通常提供身份的ID等標識信息來代表他就是他本人,如身份證,用戶名/密碼等。
包括兩個部分,一個 principals(身份),credentials(證實) 兩個部分。
即主體的標識屬性,能夠是任何東西,如用戶名、郵箱等,惟一便可。一個主體能夠有多個principals,但只有一個Primary principals,通常是用戶名/密碼/手機號。
即只有主體知道的安全值,如密碼/數字證書等
最多見的身份認證就是 用戶名和密碼。
其中,身份 principals 是用戶名,惟一的,
證實 credentials 是密碼,只有當前身份的那個用戶才知道的憑證。
編寫一個小的 Demo,來演示一下 Shiro 的具體使用。
在 pom.xml 文件中,添加shiro 和junit 測試的 依賴
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yjl.shiro</groupId> <artifactId>Shiro_Ini</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> <build> <plugins> <!-- 編譯的jdk版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
用戶的身份密碼,角色權限等信息,能夠暫時配置在 .ini 文件裏面。
Shiro 支持從 .ini 配置文件裏面讀取數據, 但要保證文件的格式正確。
咱們往裏面添加兩個用戶, yuejl 和yuezl 兩個用戶,密碼均爲 1234.
# 配置用戶的信息 [users] #用戶名=密碼 yuejl=1234 yuezl=1234
shiro.ini 文件要放置在 classpath 目錄下。
package com.yjl.demo; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; /** * * @author 兩個蝴蝶飛 * Shiro 的第一個演示文件 */ public class ShiroDemo1 { public static void main(String[] args) { //1. 建立工廠 Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini"); //2. 從工廠裏面獲取 SecurityManager SecurityManager securityManager=factory.getInstance(); //3. 經過工具類設置 securityManager SecurityUtils.setSecurityManager(securityManager); //4. 獲取當前登陸的用戶 Subject subject=SecurityUtils.getSubject(); //5. 拼裝用戶的身份和密碼Token UsernamePasswordToken token=new UsernamePasswordToken("yuezl","1234"); //1.正確密碼 //UsernamePasswordToken token=new UsernamePasswordToken("yuezl","123456"); //2.錯誤密碼 //6. 調用 subject 裏面的login 方法,進行登陸 try{ subject.login(token); //7.判斷用戶是否登陸成功 if(subject.isAuthenticated()){ System.out.println("用戶:"+token.getUsername()+", 登陸成功"); } }catch(Exception e){ System.out.println("用戶登陸失敗"); } } }
正確的密碼 1234,進行測試
錯誤的密碼 123456,進行測試
其中, token 對象裏面傳入的用戶名和密碼,就是咱們之後在前端用戶輸入的用戶名和密碼,
shiro.ini 裏面的用戶名和密碼,就是咱們從數據庫裏面讀取出來的用戶的用戶名和密碼。
二者是如何進行比較的呢? 是經過 subject.login() 方法進行比較的。
本章節代碼連接爲:
連接:https://pan.baidu.com/s/1FI_r9DfOhrK84k9ru0zerA 提取碼:6z3o
謝謝您的觀看,我是兩個蝴蝶飛, 若是喜歡,請關注我,再次感謝 !!!