戒色詩: 二八佳人體似酥,腰間仗劍斬凡夫,雖然不見人頭落,暗里教君骨髓枯,
關于Shiro 的教程,推薦大家看 張開濤前輩寫得 跟我學Shiro, 寫得非常好,
老蝴蝶寫得這個 Shiro 系列,側重于實際應用,所以太深奧的內容不進行講解,大家看張開濤前輩寫的Shiro 文章就好,
另,本系列shiro 內容會大量參考張開濤前輩的文章,謝謝!!!
一. Shiro的出現
一.一 為什么要出現 Shiro?
前面,我們在控制權限,保障資料隱私和安全時,都是自己撰寫的代碼程式進行相應的控制,
我們自己前面實作的 權限驗證,操作復雜,功能簡單,復用率低, 一些常見的功能,如 單點登錄,記住我,密碼加密等,很難實作,還需要根據不同的框架寫不同的過濾器或者攔截器,自己手動配置靜態的和不需要認證的頁面url.
我們希望能有一個工具,就像 Quartz 實作作業調度一樣,實作權限的控制? 我們只需要把用戶,角色,權限的資料交給這個工具,通過簡單的配置,這個工具就能自動幫我們實作認證和授權的操作,
有這個工具,這個工具就是 Shiro.
Shiro 可以幫我們快速地實作 認證和授權的功能,保障系統地安全,
一.二 Shiro的簡介和下載
Shiro 是一個強大的 Java安全框架,越來越多的人使用它,適用于 JavaSE 和 JavaEE,
可以進行 認證,授權,加密和會話管理 ,也支持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 相關概念介紹
二.一 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 的外部架構
二.二.一 外部架構圖片
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 不維護資料,只查詢,不更新,
二.三 Shiro 的內部架構
二.三.一 Shiro 的內部架構圖片
具體的功能組件

二.三.二 內部架構解釋
| 名稱 | 解釋 |
|---|---|
| Subject | 主體,可以看到主體是任何可以與應用互動的用戶 |
| SecurityManager | 所有具體的互動都是通過它進行控制的,管理著所有的Subject |
| Authenticator | 認證器,負責主體認證的,需要配置認證策略 Strategy |
| Authrizer | 授權器,用來決定主體是否有權限進行相應的操作 |
| Realm | 安全物體資料源,用于獲取資料 |
| SessionManager | 會話管理,用于管理Session |
| SessionDAO | 用于會話的CRUD |
| CacheManager | 快取管理,用于提高訪問的性能,常存盤用戶,角色,權限 |
| Cryptography | 密碼模塊,用于加密用戶的密碼等隱私資料 |
二.四 身份認證
身份認證,是在應用中誰能證明他就是他本人,一般提供身份的ID等標識資訊來表明他就是他本人,如身份證,用戶名/密碼等,
包括兩個部分,一個 principals(身份),credentials(證明) 兩個部分,
二.四.一 principals 身份
即主體的標識屬性,可以是任何東西,如用戶名、郵箱等,唯一即可,一個主體可以有多個principals,但只有一個Primary principals,一般是用戶名/密碼/手機號,
二.四.二 credentials 證明
即只有主體知道的安全值,如密碼/數字證書等
最常見的身份認證就是 用戶名和密碼,
其中,身份 principals 是用戶名,唯一的,
證明 credentials 是密碼,只有當前身份的那個用戶才知道的憑證,
三. Shiro 進行認證實體
撰寫一個小的 Demo,來演示一下 Shiro 的具體使用,
三.一 添加 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>
三.二 創建組態檔 shiro.ini
用戶的身份密碼,角色權限等資訊,可以暫時配置在 .ini 檔案里面,
Shiro 支持從 .ini 組態檔里面讀取資料, 但要保證檔案的格式正確,
我們往里面添加兩個用戶, yuejl 和yuezl 兩個用戶,密碼均為 1234.
# 配置用戶的資訊
[users]
#用戶名=密碼
yuejl=1234
yuezl=1234
shiro.ini 檔案要放置在 classpath 目錄下,
三.三 撰寫 測驗Demo
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
謝謝您的觀看,我是兩個蝴蝶飛, 如果喜歡,請關注我,再次感謝 !!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/250029.html
標籤:Java
上一篇:面試官問:為什么 MySQL 中的 utf8 并不是真正的 UTF-8 編碼?
下一篇:JDBC基本操作
