Răsfoiți Sursa

SEC-745: Added concrete failure handling strategies.

Luke Taylor 16 ani în urmă
părinte
comite
839279161d

+ 5 - 1
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;
 }

+ 40 - 0
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.
+ * <p>
+ * 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<String, String> failureUrlMap = new HashMap<String, String>();
+
+    @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);
+        }
+    }
+
+
+}

+ 5 - 5
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 <tt>true</tt>, causes any redirection URLs to be calculated minus the protocol
+     * and context path (defaults to <tt>false</tt>).
+     */
+    public void setUseRelativeContext(boolean useRelativeContext) {
         this.useRelativeContext = useRelativeContext;
     }
 }

+ 75 - 0
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;
+
+/**
+ * <tt>AuthenticationFailureHandler</tt> which performs a redirect to the value of the {@link #setDefaultFailureUrl
+ * defaultFailureUrl} property when the <tt>onAuthenticationFailure</tt> 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
+ * <tt>AuthenticationException</tt> which caused the failure.
+ * <p>
+ * If the <tt>forwardToDestination</tt> parameter is set, a <tt>RequestDispatcher.forward</tt> 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 <tt>true</tt>, performs a forward to the failure destination URL instead of a redirect. Defaults to
+     * <tt>false</tt>.
+     */
+    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;
+    }
+
+}