身份驗證,即在應用中誰能證實他就是他本人。通常提供如他們的身份 ID 一些標識信息來代表他就是他本人,如提供身份證,用戶名 / 密碼來證實。web
在 shiro 中,用戶須要提供 principals (身份)和 credentials(證實)給 shiro,從而應用能驗證用戶身份:spring
principals:身份,即主體的標識屬性,能夠是任何東西,如用戶名、郵箱等,惟一便可。一個主體能夠有多個 principals,但只有一個 Primary principals,通常是用戶名 / 密碼 / 手機號。數據庫
credentials:證實 / 憑證,即只有主體知道的安全值,如密碼 / 數字證書等。apache
最多見的 principals 和 credentials 組合就是用戶名 / 密碼了。接下來先進行一個基本的身份認證。安全
另外兩個相關的概念是以前提到的 Subject 及 Realm,分別是主體及驗證主體的數據源。測試
環境準備編碼
本文使用 Maven 構建,所以須要一點 Maven 知識。首先準備環境依賴:加密
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency>
登陸 / 退出spa
一、首先準備一些用戶身份 / 憑據(shiro.ini)(此處的ini文件其實能夠認爲是數據庫,真正的項目多是從數據庫中讀出來的)線程
此處使用 ini 配置文件,經過 [users] 指定了兩個主體:admin/admin、張三/123465。
二、測試用例
@Test public void testHelloworld() { //一、獲取SecurityManager工廠,此處使用Ini配置文件初始化SecurityManager Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //二、獲得SecurityManager實例 並綁定給SecurityUtils org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //三、獲得Subject及建立用戶名/密碼身份驗證Token(即用戶身份/憑證) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin"); try { //四、登陸,即身份驗證 subject.login(token); System.out.println("登錄成功"); } catch (AuthenticationException e) { //五、身份驗證失敗 } Assert.assertEquals(true, subject.isAuthenticated()); //斷言用戶已經登陸 //六、退出 subject.logout(); }
首先經過 new IniSecurityManagerFactory 並指定一個 ini 配置文件來建立一個 SecurityManager 工廠;
接着獲取 SecurityManager 並綁定到 SecurityUtils,這是一個全局設置,設置一次便可;
經過 SecurityUtils 獲得 Subject,其會自動綁定到當前線程;***若是在 web 環境在請求結束時須要解除綁定;而後獲取身份驗證的 Token,如用戶名 / 密碼;
4. 調用 subject.login 方法進行登陸,其會自動委託給 SecurityManager.login 方法進行登陸;
若是身份驗證失敗請捕獲 AuthenticationException 或其子類,常見的如: DisabledAccountException(禁用的賬號)、LockedAccountException(鎖定的賬號)、UnknownAccountException(錯誤的賬號)、ExcessiveAttemptsException(登陸失敗次數過多)、IncorrectCredentialsException (錯誤的憑證)、ExpiredCredentialsException(過時的憑證)等,具體請查看其繼承關係;對於頁面的錯誤消息展現,最好使用如 「用戶名 / 密碼錯誤」 而不是 「用戶名錯誤」/「密碼錯誤」,防止一些惡意用戶非法掃描賬號庫;
最後能夠調用 subject.logout 退出,其會自動委託給 SecurityManager.logout 方法退出。
從如上代碼可總結出身份驗證的步驟:
收集用戶身份 / 憑證,即如用戶名 / 密碼;
調用 Subject.login 進行登陸,若是失敗將獲得相應的 AuthenticationException 異常,根據異常提示用戶錯誤信息;不然登陸成功;
最後調用 Subject.logout 進行退出操做。
如上測試的幾個問題:
用戶身份 Token 可能不只僅是用戶名 / 密碼,也可能還有其餘的,如登陸時容許用戶名 / 郵箱 / 手機號同時登陸。