1. 程式人生 > >Shiro入門學習---使用自定義Realm完成認證|練氣中期

Shiro入門學習---使用自定義Realm完成認證|練氣中期

## 寫在前面 在上一篇文章[《shiro認證流程原始碼分析--練氣初期》](https://www.cnblogs.com/bingfengdev/p/13768829.html)當中,我們簡單分析了一下shiro的認證流程。不難發現,如果我們需要使用其他資料來源的資訊完成認證操作,我們需要自定義Realm繼承AuthorizingRealm類,並實現兩個方法,分別對應授權和認證。 在這一篇文章當中,我們將介紹如何自定義Realm物件,完成認證資訊資料來源的切換。 ## 自定義Reaml ```java /**自定義Realm物件 * @author 賴柄灃 [email protected] * @version 1.0 * @date 2020/10/4 11:00 */ public class MySqlRealm extends AuthorizingRealm { /**授權,今天暫不實現 * @author 賴柄灃 [email protected] * @date 2020-10-04 11:01:50 * @param principalCollection * @return org.apache.shiro.authz.AuthorizationInfo * @throws AuthenticationException * @version 1.0 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } /**認證 * @author 賴柄灃 [email protected] * @date 2020-10-04 11:01:50 * @param authenticationToken * @return org.apache.shiro.authz.AuthorizationInfo * @throws AuthenticationException * @version 1.0 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 1. 從token中獲取使用者名稱 String principal = (String) authenticationToken.getPrincipal(); //2. 根據使用者名稱查詢資料庫(模擬) if (principal == "xiangbei") { AuthenticationInfo authInfo = new SimpleAuthenticationInfo("xiangbei","123",this.getName()); return authInfo; } return null; } } ``` ## 在認證器中使用自定義Realm進行認證 ```java /**認證管理器 * @author 賴柄灃 [email protected] * @version 1.0 * @date 2020/10/4 11:11 */ public class CurrentSystemAuthenticator { private DefaultSecurityManager securityManager; public CurrentSystemAuthenticator() { //建立安全管理器 securityManager = new DefaultSecurityManager(); //設定自定義realm this.securityManager.setRealm(new MySqlRealm()); //將安全管理器設定到安全工具類中 SecurityUtils.setSecurityManager(securityManager); } public void authenticate(String username,String password){ //獲取當前登入主題 Subject subject = SecurityUtils.getSubject(); //生成toeken UsernamePasswordToken token = new UsernamePasswordToken(username, password); //進行認證 try { subject.login(token); }catch (UnknownAccountException | IncorrectCredentialsException e) { System.out.println("使用者名稱或密碼不正確"); } //列印認證狀態 if (subject.isAuthenticated()){ System.out.println(token.getPrincipal()+" 認證通過!"); }else { System.out.println(token.getPrincipal()+" 認證未通過!"); } } } ``` ## 進行測試 ### 認證通過的情況 #### 用例程式碼 ```Java /**測試認證 * @author 賴柄灃 [email protected] * @version 1.0 * @date 2020/9/21 0:49 */ public class TestAuthenticator { private Authenticator authenticator=null; @Before public void init() { authenticator = new Authenticator(); } @Test public void testAuth(){ authenticator.authenticate("xiangbei","123"); } } ``` #### 輸出 ``` xiangbei 認證通過! ``` ### 認證不通過的情況 認證不通過的情況在shiro當中分為幾種情況,具體可以檢視我的上一篇文章[《shiro認證流程原始碼分析--練氣初期》](https://juejin.im/post/6879409669224267783) 關於shiro認證異常的分析,常用的有如下幾種: 1. 賬戶不正確(不存在) 2. 密碼錯誤 3. 賬戶被鎖定 4. 密碼過期 在實際專案中為了安全起見,賬戶不正確和密碼錯誤統一返回“使用者名稱或密碼不正確”類似的的提示,避免造成賬戶洩露。 下面針對這種情況給予演示 #### 用例程式碼 ```java /** * @author 賴柄灃 [email protected] * @version 1.0 * @date 2020/10/4 11:20 */ public class AuthcTest { private CurrentSystemAuthenticator authenticator; @Before public void init() { this.authenticator = new CurrentSystemAuthenticator(); } @Test public void testAuthc(){ this.authenticator.authenticate("xiangbei","13"); } } ``` #### 輸出 ``` 使用者名稱或密碼不正確 xiangbei 認證未通過! ``` ## 寫在最後 這一篇文章主要是帶領大家瞭解一下如何通過自定義Realm物件完成shiro認證資料來源的切換。對於MySQL的整合,我們將在後面的文章當中整合SpringBoot時介紹。 下一篇文章將簡單介紹shiro中的密碼加密以及如何配置使用。 本文所涉及的程式碼下載地址:https://github.com/code81192/art-demo/tree/master/shiro-auth