Shiro 筆記 身份驗證
阿新 • • 發佈:2018-11-13
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(); } }