ModularRealmAuthenticator类

likesyour 2016-11-04

ModularRealmAuthenticator类主要是用来实现项目中出现多realm的情况下,根据认证策略来对各个realm进行认证,它继承了AbstractAuthenticator抽象类,先对其解析如下:

1.AbstractAuthenticator抽象类

可以参照AbstractAuthenticator抽象类源码解析,主要实现了认证并且在认证成功或者失败后通知认证监听器组。

2.ModularRealmAuthenticator类

2.1.属性数据

private Collection<Realm> realms;//多个安全数据源

private AuthenticationStrategy authenticationStrategy;//认证策略

2.2.构造方法(默认的认证策略是至少一个成功的策略)

public ModularRealmAuthenticator() {
        this.authenticationStrategy = new AtLeastOneSuccessfulStrategy();
}

2.3.设置realm集合

public void setRealms(Collection<Realm> realms) {
        this.realms = realms;
}

2.4.获取realm集合

protected Collection<Realm> getRealms() {
        return this.realms;
}

2.5.获取认证策略

public AuthenticationStrategy getAuthenticationStrategy() {
        return authenticationStrategy;
}

2.7.设置认证策略

public void setAuthenticationStrategy(AuthenticationStrategy authenticationStrategy) {
        this.authenticationStrategy = authenticationStrategy;
}

2.8.验证realms集合不为空(如果为空,则抛出异常)

protected void assertRealmsConfigured() throws IllegalStateException {
        Collection<Realm> realms = getRealms();
        if (CollectionUtils.isEmpty(realms)) {
            String msg = "Configuration error:  No realms have been configured!  One or more realms must be " +
                    "present to execute an authentication attempt.";
            throw new IllegalStateException(msg);
        }
    }

2.9.单一realm的认证

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);
        }
        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;
    }

2.10.多realm认证

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;
    }

2.11.认证操作(判断realm的个数,如果realm为一个,则进行单realm认证;如果realm为多个,则进行多realm认证,实现了AbstractAuthenticator的方法)

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        assertRealmsConfigured();
        Collection<Realm> realms = getRealms();
        if (realms.size() == 1) {
            return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
        } else {
            return doMultiRealmAuthentication(realms, authenticationToken);
        }
    }

2.12.登出(覆盖了AbstractAuthenticator的方法)

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);
                }
            }
        }
    }

相关推荐

Mr丶Yang / 0评论 2016-11-04