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

寫在前面

在上一篇文章《shiro認證流程源碼分析--練氣初期》當中,咱們簡單分析了一下shiro的認證流程。不難發現,若是咱們須要使用其餘數據源的信息完成認證操做,咱們須要自定義Realm繼承AuthorizingRealm類,並實現兩個方法,分別對應受權和認證。html

在這一篇文章當中,咱們將介紹如何自定義Realm對象,完成認證信息數據源的切換。java

自定義Reaml

/**自定義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;
    }
}

在認證器中使用自定義Realm進行認證

/**認證管理器
 * @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

  1. 帳戶不正確(不存在)
  2. 密碼錯誤
  3. 帳戶被鎖定
  4. 密碼過時

在實際項目中爲了安全起見,帳戶不正確和密碼錯誤統一返回「用戶名或密碼不正確」相似的的提示,避免形成帳戶泄露。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

相關文章
相關標籤/搜索