在上一篇文章《shiro認證流程源碼分析--練氣初期》當中,咱們簡單分析了一下shiro的認證流程。不難發現,若是咱們須要使用其餘數據源的信息完成認證操做,咱們須要自定義Realm繼承AuthorizingRealm類,並實現兩個方法,分別對應受權和認證。html
在這一篇文章當中,咱們將介紹如何自定義Realm對象,完成認證信息數據源的切換。java
/**自定義Realm對象 * @author 賴柄灃 bingfengdev@aliyun.com * @version 1.0 * @date 2020/10/4 11:00 */ public class MySqlRealm extends AuthorizingRealm { /**受權,今天暫不實現 * @author 賴柄灃 bingfengdev@aliyun.com * @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 賴柄灃 bingfengdev@aliyun.com * @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; } }
/**認證管理器 * @author 賴柄灃 bingfengdev@aliyun.com * @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()+" 認證未經過!"); } } }
/**測試認證 * @author 賴柄灃 bingfengdev@aliyun.com * @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認證流程源碼分析--練氣初期》 關於shiro認證異常的分析,經常使用的有以下幾種:mysql
在實際項目中爲了安全起見,帳戶不正確和密碼錯誤統一返回「用戶名或密碼不正確」相似的的提示,避免形成帳戶泄露。git
下面針對這種狀況給予演示github
/** * @author 賴柄灃 bingfengdev@aliyun.com * @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時介紹。sql
下一篇文章將簡單介紹shiro中的密碼加密以及如何配置使用。數據庫
本文所涉及的代碼下載地址:https://github.com/code81192/art-demo/tree/master/shiro-authc-mysqlapache