package com.hwlcn.security.authc; import com.hwlcn.security.subject.PrincipalCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; public abstract class AbstractAuthenticator implements Authenticator, LogoutAware { private static final Logger log = LoggerFactory.getLogger(AbstractAuthenticator.class); private Collection<AuthenticationListener> listeners; public AbstractAuthenticator() { listeners = new ArrayList<AuthenticationListener>(); } @SuppressWarnings({"UnusedDeclaration"}) public void setAuthenticationListeners(Collection<AuthenticationListener> listeners) { if (listeners == null) { this.listeners = new ArrayList<AuthenticationListener>(); } else { this.listeners = listeners; } } @SuppressWarnings({"UnusedDeclaration"}) public Collection<AuthenticationListener> getAuthenticationListeners() { return this.listeners; } protected void notifySuccess(AuthenticationToken token, AuthenticationInfo info) { for (AuthenticationListener listener : this.listeners) { listener.onSuccess(token, info); } } protected void notifyFailure(AuthenticationToken token, AuthenticationException ae) { for (AuthenticationListener listener : this.listeners) { listener.onFailure(token, ae); } } protected void notifyLogout(PrincipalCollection principals) { for (AuthenticationListener listener : this.listeners) { listener.onLogout(principals); } } public void onLogout(PrincipalCollection principals) { notifyLogout(principals); } public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException { if (token == null) { throw new IllegalArgumentException("Method argumet (authentication token) cannot be null."); } if (log.isTraceEnabled()) log.trace("Authentication attempt received for token [{}]", token); AuthenticationInfo info; try { 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) { 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); } try { notifyFailure(token, ae); } catch (Throwable t2) { if (log.isWarnEnabled()) { String msg = "Unable to send notification for failed authentication attempt - listener error?. " + "Please check your AuthenticationListener implementation(s). Logging sending exception " + "and propagating original AuthenticationException instead..."; log.warn(msg, t2); } } throw ae; } log.debug("Authentication successful for token [{}]. Returned account [{}]", token, info); notifySuccess(token, info); return info; } protected abstract AuthenticationInfo doAuthenticate(AuthenticationToken token) throws AuthenticationException; }