shiro 用户认证源码分析

定义接口获取用户用户名密码 AuthenticationToken,在

子类实现:

 

Authenticator接口用来认证用户,可以看出参数就是AutenticationToken,从中获取用户名密码进行验证

AuthenticationInfo和AuthenticationToken比较相似,AuthenticationInfo是已经验证过的保存的用户信息,而AuthenticationToken是第三方通过login发送过来等待验证的用户信息。SaltedAuthenticationInfo定义了获取盐的方法,MergableAuthenticationInfo定义了把一个AuthenticationInfo和现有的AuthenticationInfo合并的方法。

LogoutAware当用户退出的时候的回调接口

AbstractAuthenticator抽象类,实现了接口方法authentication(AuthentiationToken),调用了模板方法doAuthentication(AuthenticationToken)来验证用户,如果成功调用notifySuccess循环调用集合listeners中的监听器,调用监听器的onSuccess方法,如果失败掉用notifyFailure方法,调用监听器的onFailure方法,同时抛出认证异常。实现了接口方法onLogout,在此方法中调用了notifyLogout遍历集合listeners中的监听器,调用监听器的onLogout方法。

 

用户认证监听器接口:

ModularRealmAuthenticator是接口Authenticator的默认实现类,主要有以下功能:

  1:实现父类模板方法:doAuthenticator(AuthenticationToken) ,根据realm数量调用doSingleRealmAuthentication或者doMultiRealmAuthentication方法

2:重写父类onLogout,调用父类onLogout,然后遍历调用realm集合中的realm的onLogout方法

 protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        //验证realm集合存在
        assertRealmsConfigured();
        Collection<Realm> realms = getRealms();
        if (realms.size() == 1) {
            return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
        } else {
            return doMultiRealmAuthentication(realms, authenticationToken);
        }
    }
 protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
        if (!realm.supports(token)) {
            String msg = "Realm [" + realm + "] does not support authentication token [" +
                    token + "].  Please ensure that the appropriate Realm implementation is " +
                    "configured correctly or that the realm accepts AuthenticationTokens of this type.";
            throw new UnsupportedTokenException(msg);
        }
        //最终调用的realm的getAuthenticationInfo获取AuthenticationInfo
        AuthenticationInfo info = realm.getAuthenticationInfo(token);
        if (info == null) {
            String msg = "Realm [" + realm + "] was unable to find account data for the " +
                    "submitted AuthenticationToken [" + token + "].";
            throw new UnknownAccountException(msg);
        }
        return info;
    }
   protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {

        AuthenticationStrategy strategy = getAuthenticationStrategy();

        AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);

        if (log.isTraceEnabled()) {
            log.trace("Iterating through {} realms for PAM authentication", realms.size());
        }

        for (Realm realm : realms) {

            aggregate = strategy.beforeAttempt(realm, token, aggregate);

            if (realm.supports(token)) {

                log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);

                AuthenticationInfo info = null;
                Throwable t = null;
                try {
                    info = realm.getAuthenticationInfo(token);
                } catch (Throwable throwable) {
                    t = throwable;
                    if (log.isDebugEnabled()) {
                        String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";
                        log.debug(msg, t);
                    }
                }

                aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);

            } else {
                log.debug("Realm [{}] does not support token {}.  Skipping realm.", realm, token);
            }
        }

        aggregate = strategy.afterAllAttempts(token, aggregate);

        return aggregate;
    }

 

public void onLogout(PrincipalCollection principals) {
        super.onLogout(principals);
        Collection<Realm> realms = getRealms();
        if (!CollectionUtils.isEmpty(realms)) {
            for (Realm realm : realms) {
                if (realm instanceof LogoutAware) {
                    ((LogoutAware) realm).onLogout(principals);
                }
            }
        }
    }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值