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

相关文章
相关标签/搜索