From 839279161d0873c5b07c1278ef6e70aedd4a4822 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sat, 13 Dec 2008 23:34:15 +0000 Subject: [PATCH] SEC-745: Added concrete failure handling strategies. --- .../ui/AuthenticationFailureHandler.java | 6 +- ...onMappingAuthenticationFailureHandler.java | 40 ++++++++++ ...uestAwareAuthenticationSuccessHandler.java | 10 +-- ...SimpleUrlAuthenticationFailureHandler.java | 75 +++++++++++++++++++ 4 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java create mode 100644 core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java diff --git a/core/src/main/java/org/springframework/security/ui/AuthenticationFailureHandler.java b/core/src/main/java/org/springframework/security/ui/AuthenticationFailureHandler.java index 996f279310..66ec030e8c 100644 --- a/core/src/main/java/org/springframework/security/ui/AuthenticationFailureHandler.java +++ b/core/src/main/java/org/springframework/security/ui/AuthenticationFailureHandler.java @@ -1,5 +1,8 @@ package org.springframework.security.ui; +import java.io.IOException; + +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -26,5 +29,6 @@ public interface AuthenticationFailureHandler { * @param response the response. * @param exception the exception which was thrown to reject the authentication request. */ - void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception); + void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException, ServletException; } diff --git a/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java b/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java new file mode 100644 index 0000000000..205c570c02 --- /dev/null +++ b/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java @@ -0,0 +1,40 @@ +package org.springframework.security.ui; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.AuthenticationException; +import org.springframework.security.util.RedirectUtils; + +/** + * Uses the internal map of exceptions types to URLs to determine the destination on authentication failure. The keys + * are the full exception class names. + *

+ * If a match isn't found, falls back to the behaviour of the parent class, + * {@link SimpleUrlAuthenticationFailureHandler}. + * + * @author Luke Taylor + * @version $Id$ + * @since 2.5 + */ +public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + private Map failureUrlMap = new HashMap(); + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException { + String url = failureUrlMap.get(exception.getClass().getName()); + + if (url != null) { + RedirectUtils.sendRedirect(request, response, url, isUseRelativeContext()); + } else { + super.onAuthenticationFailure(request, response, exception); + } + } + + +} diff --git a/core/src/main/java/org/springframework/security/ui/SavedRequestAwareAuthenticationSuccessHandler.java b/core/src/main/java/org/springframework/security/ui/SavedRequestAwareAuthenticationSuccessHandler.java index be2bde2bdc..61e03b9dbd 100644 --- a/core/src/main/java/org/springframework/security/ui/SavedRequestAwareAuthenticationSuccessHandler.java +++ b/core/src/main/java/org/springframework/security/ui/SavedRequestAwareAuthenticationSuccessHandler.java @@ -74,10 +74,6 @@ public class SavedRequestAwareAuthenticationSuccessHandler implements Authentica */ private boolean alwaysUseDefaultTargetUrl = false; - /** - * If true, causes any redirection URLs to be calculated minus the protocol - * and context path (defaults to false). - */ private boolean useRelativeContext = false; public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, @@ -213,7 +209,11 @@ public class SavedRequestAwareAuthenticationSuccessHandler implements Authentica this.targetUrlParameter = targetUrlParameter; } - void setUseRelativeContext(boolean useRelativeContext) { + /** + * If true, causes any redirection URLs to be calculated minus the protocol + * and context path (defaults to false). + */ + public void setUseRelativeContext(boolean useRelativeContext) { this.useRelativeContext = useRelativeContext; } } diff --git a/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java b/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java new file mode 100644 index 0000000000..31ed2e3885 --- /dev/null +++ b/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java @@ -0,0 +1,75 @@ +package org.springframework.security.ui; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.AuthenticationException; +import org.springframework.security.util.RedirectUtils; + +/** + * AuthenticationFailureHandler which performs a redirect to the value of the {@link #setDefaultFailureUrl + * defaultFailureUrl} property when the onAuthenticationFailure method is called. + * If the property has not been set it will send a 401 response to the client, with the error message from the + * AuthenticationException which caused the failure. + *

+ * If the forwardToDestination parameter is set, a RequestDispatcher.forward call will be made to + * the destination instead of + * + * @author Luke Taylor + * @version $Id$ + * @since 2.5 + */ +public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler { + private String defaultFailureUrl; + private boolean forwardToDestination = false; + /** + * If true, causes any redirection URLs to be calculated minus the protocol + * and context path (defaults to false). + */ + private boolean useRelativeContext = false; + + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException { + if (defaultFailureUrl == null) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed:" + exception.getMessage()); + } else { + RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext); + } + } + + /** + * The URL which will be used as the failure destination. + * + * @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp". + */ + public void setDefaultTargetUrl(String defaultFailureUrl) { + this.defaultFailureUrl = defaultFailureUrl; + } + + protected boolean isForwardToDestination() { + return forwardToDestination; + } + + /** + * If set to true, performs a forward to the failure destination URL instead of a redirect. Defaults to + * false. + */ + public void setForwardToDestination(boolean forwardToDestination) { + this.forwardToDestination = forwardToDestination; + } + + protected boolean isUseRelativeContext() { + return useRelativeContext; + } + + /** + * If true, causes any redirection URLs to be calculated minus the protocol + * and context path (defaults to false). + */ + public void setUseRelativeContext(boolean useRelativeContext) { + this.useRelativeContext = useRelativeContext; + } + +}