ModularRealmAuthenticator类

The ModularRealmAuthenticator class is mainly used to authenticate each realm according to the authentication strategy when there are multiple realms in the project. It inherits the AbstractAuthenticator abstract class and parses it as follows:

1.AbstractAuthenticator abstract class

You can refer to the source code analysis of the AbstractAuthenticator abstract class, which mainly implements authentication and notifies the authentication listener group after the authentication succeeds or fails.

2.ModularRealmAuthenticator类

2.1. Attribute data

private Collection<Realm> realms;//Multiple secure data sources

private AuthenticationStrategy authenticationStrategy;//Authentication strategy

2.2. Constructor (the default authentication strategy is at least one successful strategy)

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

2.3. Set realm collection

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

2.4. Get realm collection

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

2.5. Get the authentication policy

public AuthenticationStrategy getAuthenticationStrategy() {
        return authenticationStrategy;
}

2.7. Set the authentication policy

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

2.8. Verify that the realms collection is not empty (if it is, throw an exception)

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. Authentication of a single 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. Multi-realm authentication

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. Authentication operation (judging the number of realm, if the realm is one, perform single realm authentication; if there are multiple realm, perform multi-realm authentication, implementing the method of 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. Logout (overrides the method of 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);
                }
            }
        }
    }

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326580883&siteId=291194637