package org.apereo.cas.authentication; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Authentication raised by {@link AuthenticationManager} to signal authentication failure. * Authentication failure typically occurs when one or more {@link AuthenticationHandler} components * fail to authenticate credentials. This exception contains information about handler successes * and failures that may be used by higher-level components to determine subsequent behavior. * * @author Marvin S. Addison * @since 4.0.0 */ public class AuthenticationException extends RuntimeException { /** Serialization metadata. */ private static final long serialVersionUID = -6032827784134751797L; /** Immutable map of handler names to the errors they raised. */ private final Map<String, Class<? extends Exception>> handlerErrors; /** Immutable map of handler names to an authentication success metadata instance. */ private final Map<String, HandlerResult> handlerSuccesses; /** * Creates a new instance for the case when no handlers were attempted, i.e. no successes or failures. * * @param msg the msg */ public AuthenticationException(final String msg) { this( msg, Collections.emptyMap(), Collections.emptyMap()); } /** * Instantiates a new Authentication exception. */ public AuthenticationException() { this("No supported authentication handlers found for given credentials"); } /** * Creates a new instance for the case when no handlers succeeded. * * @param handlerErrors Map of handler names to errors. */ public AuthenticationException(final Map<String, Class<? extends Exception>> handlerErrors) { this(handlerErrors, Collections.emptyMap()); } /** * Creates a new instance for the case when there are both handler successes and failures. * * @param handlerErrors Map of handler names to errors. * @param handlerSuccesses Map of handler names to authentication successes. */ public AuthenticationException( final Map<String, Class<? extends Exception>> handlerErrors, final Map<String, HandlerResult> handlerSuccesses) { this( String.format("%s errors, %s successes", handlerErrors.size(), handlerSuccesses.size()), handlerErrors, handlerSuccesses); } /** * Creates a new instance for the case when there are both handler successes and failures and a custom * error message is required. * * @param message the message associated with this error. * @param handlerErrors Map of handler names to errors. * @param handlerSuccesses Map of handler names to authentication successes. */ public AuthenticationException( final String message, final Map<String, Class<? extends Exception>> handlerErrors, final Map<String, HandlerResult> handlerSuccesses) { super(message); this.handlerErrors = new HashMap<>(handlerErrors); this.handlerSuccesses = new HashMap<>(handlerSuccesses); } /** * Gets an unmodifiable map of handler names to errors. * * @return Immutable map of handler names to errors. */ public Map<String, Class<? extends Exception>> getHandlerErrors() { return this.handlerErrors; } /** * Gets an unmodifiable map of handler names to authentication successes. * * @return Immutable map of handler names to authentication successes. */ public Map<String, HandlerResult> getHandlerSuccesses() { return this.handlerSuccesses; } }