Shiro源码学习(四)登录和权限鉴定

登录


Subject结构

首先看下我们在使用登录时用到的Subject结构:


可以看到,这个接口的功能就是与登录登出、权限鉴定相关;

另外,这个接口被WebSubject继承,这也是个接口,同时还继承了RequestPairSource,为Subject添加了获取Request和Response的能力。下面是它的结构:


对Subject接口的实现类有两个:DelegatingSubject 和 WebDelegatingSubject,继承关系如下:


关于登录和权限鉴定的功能都在 DelegatingSubject 中实现,而  WebDelegatingSubject 增加的功能都是和获取请求Request和响应Response实例相关。

登录--login

接下来看下DelegateSubject的 login实现:

    public void login(AuthenticationToken token) throws AuthenticationException {
        clearRunAsIdentitiesInternal();//清楚放在Session中的属性
		//执行的登录的主要逻辑实现处
        Subject subject = securityManager.login(this, token);

		//后面代码功能为:获取登陆后的认证信息,设置当前登录状态和对Session进行进一步的包装
		//略……

    }

可以看到,登录的实现托付给了 SecurityManager 来实现,具体实现类是DefaultSecurityManager,实现如下:

    public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info;
        try {
            info = authenticate(token);	//执行登录
        } catch (AuthenticationException ae) {
            //登录失败时的处理(省略try/catch结构)
            onFailedLogin(token, ae, subject);
            throw ae; //propagate
        }
		//登录成功后的处理
        Subject loggedIn = createSubject(token, info, subject);
        onSuccessfulLogin(token, info, loggedIn);

        return loggedIn;
    }
执行登录到逻辑放到了 authenticate 中:


可以看出,登录的逻辑又再一次被委托到了专门的认证器(Authenticator)中,我们直接看下它的实现类(

ModularRealmAuthenticator
)源码:
    public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

        if (token == null) {
            throw new IllegalArgumentException("Method argument (authentication token) cannot be null.");
        }
        AuthenticationInfo info;
        try {
			//执行 token 验证
            info = doAuthenticate(token);
			//没有该用户异常
            if (info == null) {
                String msg = "No account information found for authentication token [" + token + "] by this " +
                        "Authenticator instance.  Please check that it is configured correctly.";
                throw new AuthenticationException(msg);
            }
        } catch (Throwable t) {
            AuthenticationException ae = null;
            if (t instanceof AuthenticationException) {
                ae = (AuthenticationException) t;
            }
            if (ae == null) {
		//并非是Shiro抛出的登录相关异常,Shiro的处理是将其包装成AuthenticationException,打印warn日志,并返回错误信息
                //Exception thrown was not an expected AuthenticationException.  Therefore it is probably a little more
                //severe or unexpected.  So, wrap in an AuthenticationException, log to warn, and propagate:
                String msg = "Authentication failed for token submission [" + token + "].  Possible unexpected " +
                        "error? (Typical or expected login exceptions should extend from AuthenticationException).";
                ae = new AuthenticationException(msg, t);
                if (log.isWarnEnabled())
                    log.warn(msg, t);
            }
            //主要是通知相关的监听器 listens 处理登录失败的结果(省略try、catch)
            notifyFailure(token, ae);

            throw ae;//抛出异常
        }

        log.d
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值