1. 程式人生 > >Shiro 筆記 身份驗證

Shiro 筆記 身份驗證

https://www.w3cschool.cn/shiro/xgj31if4.html

shiro筆記。

package com.dudu.course1;

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.junit.Assert;
import org.junit.Test;

/**
 * 身份驗證
 * 身份驗證,即在應用中誰能證明他就是他本人。一般提供如他們的身份 ID 一些標識資訊來表明他就是他本人,如提供身份證,使用者名稱 / 密碼來證明。
 * 在 shiro 中,使用者需要提供 principals (身份)和 credentials(證明)給 shiro,從而應用能驗證使用者身份:
 * principals:身份,即主體的標識屬性,可以是任何東西,如使用者名稱、郵箱等,唯一即可。一個主體可以有多個 principals,但只有一個 Primary principals,一般是使用者名稱 / 密碼 / 手機號。	
 * credentials:證明 / 憑證,即只有主體知道的安全值,如密碼 / 數字證書等。
 * 最常見的 principals 和 credentials 組合就是使用者名稱 / 密碼了。接下來先進行一個基本的身份認證。	
 * 另外兩個相關的概念是之前提到的 Subject 及 Realm,分別是主體及驗證主體的資料來源。
 * @author xl
 * 首先通過 new IniSecurityManagerFactory 並指定一個 ini 配置檔案來建立一個 SecurityManager 工廠;
 * 接著獲取 SecurityManager 並繫結到 SecurityUtils,這是一個全域性設定,設定一次即可;
 * 通過 SecurityUtils 得到 Subject,其會自動繫結到當前執行緒;如果在 web 環境在請求結束時需要解除繫結;然後獲取身份驗證的 Token,如使用者名稱 / 密碼;
 * 呼叫 subject.login 方法進行登入,其會自動委託給 SecurityManager.login 方法進行登入;
 * 如果身份驗證失敗請捕獲 AuthenticationException 或其子類,常見的如: DisabledAccountException(禁用的帳號)、LockedAccountException(鎖定的帳號)、UnknownAccountException(錯誤的帳號)、ExcessiveAttemptsException(登入失敗次數過多)、IncorrectCredentialsException (錯誤的憑證)、ExpiredCredentialsException(過期的憑證)等,具體請檢視其繼承關係;對於頁面的錯誤訊息展示,最好使用如 “使用者名稱 / 密碼錯誤” 而不是 “使用者名稱錯誤”/“密碼錯誤”,防止一些惡意使用者非法掃描帳號庫;
 * 最後可以呼叫 subject.logout 退出,其會自動委託給 SecurityManager.logout 方法退出。
 * 從如上程式碼可總結出身份驗證的步驟:
 * 收集使用者身份 / 憑證,即如使用者名稱 / 密碼;
 * 呼叫 Subject.login 進行登入,如果失敗將得到相應的 AuthenticationException 異常,根據異常提示使用者錯誤資訊;否則登入成功;
 * 最後呼叫 Subject.logout 進行退出操作。
 * 如上測試的幾個問題:
 * 使用者名稱 / 密碼硬編碼在 ini 配置檔案,以後需要改成如資料庫儲存,且密碼需要加密儲存;
 * 使用者身份 Token 可能不僅僅是使用者名稱 / 密碼,也可能還有其他的,如登入時允許使用者名稱 / 郵箱 / 手機號同時登入。
 * 
 */
public class ShiroTest1 {
	
	@Test
	public void helloWorld(){
		//1、獲取SecurityManager工廠,此處使用Ini配置檔案初始化SecurityManager
		IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		//2、得到SecurityManager例項 並繫結給SecurityUtils 
		SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);
		//3、得到Subject及建立使用者名稱/密碼身份驗證Token(即使用者身份/憑證)
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
		try {
			//4、登入,即身份驗證
	        subject.login(token);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//斷言用於測試相當於if
		Assert.assertEquals(true, subject.isAuthenticated()); //斷言使用者已經登入
		    //6、退出
		subject.logout();
	}
}