diff --git a/cas/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java b/cas/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java
index 1860f18e76..7438e04591 100644
--- a/cas/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java
+++ b/cas/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java
@@ -78,7 +78,7 @@ public class CasProcessingFilter extends AbstractProcessingFilter {
private ProxyGrantingTicketStorage proxyGrantingTicketStorage;
//~ Methods ========================================================================================================
- public Authentication attemptAuthentication(final HttpServletRequest request)
+ public Authentication attemptAuthentication(final HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
final String username = CAS_STATEFUL_IDENTIFIER;
String password = request.getParameter("ticket");
diff --git a/cas/src/test/java/org/springframework/security/ui/cas/CasProcessingFilterTests.java b/cas/src/test/java/org/springframework/security/ui/cas/CasProcessingFilterTests.java
index 49729f07e0..e377bd6b8e 100644
--- a/cas/src/test/java/org/springframework/security/ui/cas/CasProcessingFilterTests.java
+++ b/cas/src/test/java/org/springframework/security/ui/cas/CasProcessingFilterTests.java
@@ -22,6 +22,7 @@ import org.springframework.security.AuthenticationException;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
/**
@@ -31,26 +32,8 @@ import org.springframework.mock.web.MockHttpServletRequest;
* @version $Id$
*/
public class CasProcessingFilterTests extends TestCase {
- //~ Constructors ===================================================================================================
-
- public CasProcessingFilterTests() {
- super();
- }
-
- public CasProcessingFilterTests(String arg0) {
- super(arg0);
- }
-
//~ Methods ========================================================================================================
- public static void main(String[] args) {
- junit.textui.TestRunner.run(CasProcessingFilterTests.class);
- }
-
- public final void setUp() throws Exception {
- super.setUp();
- }
-
public void testGetters() {
CasProcessingFilter filter = new CasProcessingFilter();
assertEquals("/j_spring_cas_security_check", filter.getDefaultFilterProcessesUrl());
@@ -66,7 +49,7 @@ public class CasProcessingFilterTests extends TestCase {
filter.setAuthenticationManager(authMgr);
filter.init(null);
- Authentication result = filter.attemptAuthentication(request);
+ Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertTrue(result != null);
}
@@ -81,7 +64,7 @@ public class CasProcessingFilterTests extends TestCase {
filter.init(null);
try {
- filter.attemptAuthentication(request);
+ filter.attemptAuthentication(request, new MockHttpServletResponse());
fail("Should have thrown AuthenticationException");
} catch (AuthenticationException expected) {
assertTrue(true);
diff --git a/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java b/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java
index e4ef0f8570..5b626ab3ee 100644
--- a/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java
+++ b/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java
@@ -24,6 +24,7 @@ import org.springframework.security.ui.logout.SecurityContextLogoutHandler;
import org.springframework.security.util.UrlUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
@@ -61,7 +62,8 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
public void afterPropertiesSet() throws Exception {
Assert.notNull(sessionRegistry, "SessionRegistry required");
- Assert.isTrue(UrlUtils.isValidRedirectUrl(expiredUrl), expiredUrl + " isn't a valid redirect URL");
+ Assert.isTrue(expiredUrl == null || UrlUtils.isValidRedirectUrl(expiredUrl),
+ expiredUrl + " isn't a valid redirect URL");
}
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
@@ -120,7 +122,7 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
}
public void setLogoutHandlers(LogoutHandler[] handlers) {
- Assert.notNull(handlers);
+ Assert.notNull(handlers);
this.handlers = handlers;
}
diff --git a/core/src/main/java/org/springframework/security/config/ConfigUtils.java b/core/src/main/java/org/springframework/security/config/ConfigUtils.java
index f59346e89b..b6d6033e5d 100644
--- a/core/src/main/java/org/springframework/security/config/ConfigUtils.java
+++ b/core/src/main/java/org/springframework/security/config/ConfigUtils.java
@@ -157,7 +157,7 @@ abstract class ConfigUtils {
* If not empty or starting with "$" (potential placeholder), "/" or "http" it will raise an error.
*/
static void validateHttpRedirect(String url, ParserContext pc, Object source) {
- if (UrlUtils.isValidRedirectUrl(url) || url.startsWith("$")) {
+ if (!StringUtils.hasText(url) || UrlUtils.isValidRedirectUrl(url) || url.startsWith("$")) {
return;
}
pc.getReaderContext().warning(url + " is not a valid redirect URL (must start with '/' or http(s))", source);
diff --git a/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java
index 622640c0be..fe40306d2c 100644
--- a/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/FormLoginBeanDefinitionParser.java
@@ -8,6 +8,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.ui.SavedRequestAwareAuthenticationSuccessHandler;
+import org.springframework.security.ui.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint;
import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter;
import org.springframework.util.StringUtils;
@@ -37,6 +38,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
private static final String DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL + "?" + DefaultLoginPageGeneratingFilter.ERROR_PARAMETER_NAME;
private static final String ATT_SUCCESS_HANDLER_REF = "authentication-success-handler-ref";
+ private static final String ATT_FAILURE_HANDLER_REF = "authentication-failure-handler-ref";
private String defaultLoginProcessingUrl;
private String filterClassName;
@@ -56,6 +58,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
String authenticationFailureUrl = null;
String alwaysUseDefault = null;
String successHandlerRef = null;
+ String failureHandlerRef = null;
Object source = null;
@@ -82,18 +85,18 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
alwaysUseDefault = elt.getAttribute(ATT_ALWAYS_USE_DEFAULT_TARGET_URL);
loginPage = elt.getAttribute(ATT_LOGIN_PAGE);
successHandlerRef = elt.getAttribute(ATT_SUCCESS_HANDLER_REF);
+ failureHandlerRef = elt.getAttribute(ATT_FAILURE_HANDLER_REF);
if (!StringUtils.hasText(loginPage)) {
loginPage = null;
}
ConfigUtils.validateHttpRedirect(loginPage, pc, source);
-
}
ConfigUtils.registerProviderManagerIfNecessary(pc);
filterBean = createFilterBean(loginUrl, defaultTargetUrl, alwaysUseDefault, loginPage, authenticationFailureUrl,
- successHandlerRef);
+ successHandlerRef, failureHandlerRef);
filterBean.setSource(source);
filterBean.getPropertyValues().addPropertyValue("authenticationManager",
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
@@ -123,7 +126,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
}
private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String alwaysUseDefault,
- String loginPage, String authenticationFailureUrl, String successHandlerRef) {
+ String loginPage, String authenticationFailureUrl, String successHandlerRef, String failureHandlerRef) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(filterClassName);
@@ -144,17 +147,22 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
filterBuilder.addPropertyValue("successHandler", successHandler.getBeanDefinition());
}
- if (!StringUtils.hasText(authenticationFailureUrl)) {
- // Fallback to redisplaying the custom login page, if one was specified
- if (StringUtils.hasText(loginPage)) {
- authenticationFailureUrl = loginPage;
- } else {
- authenticationFailureUrl = DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL;
+ if (StringUtils.hasText(failureHandlerRef)) {
+ filterBuilder.addPropertyReference("failureHandler", failureHandlerRef);
+ } else {
+ BeanDefinitionBuilder failureHandler = BeanDefinitionBuilder.rootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class);
+ if (!StringUtils.hasText(authenticationFailureUrl)) {
+ // Fall back to redisplaying the custom login page, if one was specified.
+ if (StringUtils.hasText(loginPage)) {
+ authenticationFailureUrl = loginPage;
+ } else {
+ authenticationFailureUrl = DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL;
+ }
}
+ failureHandler.addPropertyValue("defaultFailureUrl", authenticationFailureUrl);
+ filterBuilder.addPropertyValue("failureHandler", failureHandler.getBeanDefinition());
}
- filterBuilder.addPropertyValue("authenticationFailureUrl", authenticationFailureUrl);
-
return (RootBeanDefinition) filterBuilder.getBeanDefinition();
}
diff --git a/core/src/main/java/org/springframework/security/ui/AbstractProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/AbstractProcessingFilter.java
index 5c487839c5..7f1949cb86 100644
--- a/core/src/main/java/org/springframework/security/ui/AbstractProcessingFilter.java
+++ b/core/src/main/java/org/springframework/security/ui/AbstractProcessingFilter.java
@@ -19,7 +19,6 @@ import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.AuthenticationManager;
-import org.springframework.security.util.RedirectUtils;
import org.springframework.security.util.SessionUtils;
import org.springframework.security.util.UrlUtils;
@@ -44,8 +43,6 @@ import org.springframework.util.Assert;
import java.io.IOException;
-import java.util.Properties;
-
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -128,45 +125,24 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
//~ Instance fields ================================================================================================
protected ApplicationEventPublisher eventPublisher;
-
protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
-
private AuthenticationManager authenticationManager;
-
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
- private Properties exceptionMappings = new Properties();
-
- /**
+ /*
* Delay use of NullRememberMeServices until initialization so that namespace has a chance to inject
* the RememberMeServices implementation into custom implementations.
*/
private RememberMeServices rememberMeServices = null;
- /** Where to redirect the browser to if authentication fails */
- private String authenticationFailureUrl;
-
/**
* The URL destination that this filter intercepts and processes (usually
* something like /j_spring_security_check)
*/
private String filterProcessesUrl = getDefaultFilterProcessesUrl();
- /**
- * Indicates if the filter chain should be continued prior to delegation to
- * {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse,
- * Authentication)}, which may be useful in certain environment (eg
- * Tapestry). Defaults to false.
- */
private boolean continueChainBeforeSuccessfulAuthentication = false;
- /**
- * If true, causes any redirection URLs to be calculated minus the protocol
- * and context path (defaults to false).
- */
- protected boolean useRelativeContext = false;
-
-
/**
* Tells if we on successful authentication should invalidate the
* current session. This is a common guard against session fixation attacks.
@@ -185,19 +161,16 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
private boolean allowSessionCreation = true;
- private boolean serverSideRedirect = false;
-
private SessionRegistry sessionRegistry;
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
- private AuthenticationFailureHandler failureHandler = null;
+ private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
- Assert.isTrue(UrlUtils.isValidRedirectUrl(authenticationFailureUrl), authenticationFailureUrl + " isn't a valid redirect URL");
Assert.notNull(authenticationManager, "authenticationManager must be specified");
if (rememberMeServices == null) {
@@ -206,19 +179,26 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
}
/**
- * Performs actual authentication.
- *
- * @param request from which to extract parameters and perform the
- * authentication
- *
- * @return the authenticated user
- *
- * @throws AuthenticationException if authentication fails
+ * Invokes the {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}
+ * method to determine whether the request is for authentication and should be handled by this filter.
+ * If it is an authentication request, the
+ * {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse) attemptAuthentication} will be invoked
+ * to perform the authentication. There are then three possible outcomes:
+ *
- * Indicates whether this filter should attempt to process a login request - * for the current invocation. - *
+ * Indicates whether this filter should attempt to process a login request for the current invocation. *
* It strips any parameters from the "path" section of the request URL (such
* as the jsessionid parameter in
* http://host/myapp/index.html;jsessionid=blah) before matching
* against the filterProcessesUrl property.
- *
- * Subclasses may override for special requirements, such as Tapestry - * integration. - *
+ * Subclasses may override for special requirements, such as Tapestry integration. * - * @param request as received from the filter chain - * @param response as received from the filter chain - * - * @returntrue if the filter should attempt authentication,
- * false otherwise
+ * @return true if the filter should attempt authentication, false otherwise.
*/
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
String uri = request.getRequestURI();
@@ -297,6 +262,41 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
}
+ /**
+ * Performs actual authentication.
+ * + * The implementation should do one of the following: + *
filterProcessesUrl for the
- * implementation.
+ * Specifies the default filterProcessesUrl for the implementation.
*
* @return the default filterProcessesUrl
*/
public abstract String getDefaultFilterProcessesUrl();
- protected Properties getExceptionMappings() {
- return new Properties(exceptionMappings);
- }
-
- public void setExceptionMappings(Properties exceptionMappings) {
- this.exceptionMappings = exceptionMappings;
- }
-
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
@@ -409,6 +376,12 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
this.rememberMeServices = rememberMeServices;
}
+ /**
+ * Indicates if the filter chain should be continued prior to delegation to
+ * {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse,
+ * Authentication)}, which may be useful in certain environment (such as
+ * Tapestry applications). Defaults to false.
+ */
public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
}
@@ -439,10 +412,6 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
return authenticationDetailsSource;
}
- public void setUseRelativeContext(boolean useRelativeContext) {
- this.useRelativeContext = useRelativeContext;
- }
-
protected boolean getAllowSessionCreation() {
return allowSessionCreation;
}
@@ -451,15 +420,6 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
this.allowSessionCreation = allowSessionCreation;
}
- /**
- * Tells if we are to do a server side include of the error URL instead of a 302 redirect.
- *
- * @param serverSideRedirect
- */
- public void setServerSideRedirect(boolean serverSideRedirect) {
- this.serverSideRedirect = serverSideRedirect;
- }
-
/**
* The session registry needs to be set if session fixation attack protection is in use (and concurrent
* session control is enabled).
diff --git a/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java b/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java
index 205c570c02..5282206e80 100644
--- a/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java
+++ b/core/src/main/java/org/springframework/security/ui/ExceptionMappingAuthenticationFailureHandler.java
@@ -4,11 +4,14 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.AuthenticationException;
import org.springframework.security.util.RedirectUtils;
+import org.springframework.security.util.UrlUtils;
+import org.springframework.util.Assert;
/**
* Uses the internal map of exceptions types to URLs to determine the destination on authentication failure. The keys
@@ -26,7 +29,7 @@ public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthe
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException exception) throws IOException {
+ AuthenticationException exception) throws IOException, ServletException {
String url = failureUrlMap.get(exception.getClass().getName());
if (url != null) {
@@ -36,5 +39,23 @@ public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthe
}
}
-
+ /**
+ * Sets the map of exception types (by name) to URLs.
+ *
+ * @param failureUrlMap the map keyed by the fully-qualified name of the exception class, with the corresponding
+ * failure URL as the value.
+ *
+ * @throws IllegalArgumentException if the entries are not Strings or the URL is not valid.
+ */
+ public void setExceptionMappings(Map,?> failureUrlMap) {
+ this.failureUrlMap.clear();
+ for (Map.Entry,?> entry : failureUrlMap.entrySet()) {
+ Object exception = entry.getKey();
+ Object url = entry.getValue();
+ Assert.isInstanceOf(String.class, exception, "Exception key must be a String (the exception classname).");
+ Assert.isInstanceOf(String.class, url, "URL must be a String");
+ Assert.isTrue(UrlUtils.isValidRedirectUrl((String)url), "Not a valid redirect URL: " + url);
+ this.failureUrlMap.put((String)exception, (String)url);
+ }
+ }
}
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 61e03b9dbd..384361b3ef 100644
--- a/core/src/main/java/org/springframework/security/ui/SavedRequestAwareAuthenticationSuccessHandler.java
+++ b/core/src/main/java/org/springframework/security/ui/SavedRequestAwareAuthenticationSuccessHandler.java
@@ -14,6 +14,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.security.Authentication;
import org.springframework.security.ui.savedrequest.SavedRequest;
import org.springframework.security.util.RedirectUtils;
+import org.springframework.security.util.UrlUtils;
import org.springframework.security.wrapper.SavedRequestAwareWrapper;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -163,7 +164,7 @@ public class SavedRequestAwareAuthenticationSuccessHandler implements Authentica
* @param defaultTargetUrl
*/
public void setDefaultTargetUrl(String defaultTargetUrl) {
- Assert.isTrue(defaultTargetUrl.startsWith("/") | defaultTargetUrl.startsWith("http"),
+ Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultTargetUrl),
"defaultTarget must start with '/' or with 'http(s)'");
this.defaultTargetUrl = defaultTargetUrl;
}
diff --git a/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java b/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java
index 31ed2e3885..b6a50889ea 100644
--- a/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java
+++ b/core/src/main/java/org/springframework/security/ui/SimpleUrlAuthenticationFailureHandler.java
@@ -2,11 +2,14 @@ package org.springframework.security.ui;
import java.io.IOException;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.AuthenticationException;
import org.springframework.security.util.RedirectUtils;
+import org.springframework.security.util.UrlUtils;
+import org.springframework.util.Assert;
/**
* AuthenticationFailureHandler which performs a redirect to the value of the {@link #setDefaultFailureUrl
@@ -31,11 +34,15 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
private boolean useRelativeContext = false;
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException exception) throws IOException {
+ AuthenticationException exception) throws IOException, ServletException {
if (defaultFailureUrl == null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed:" + exception.getMessage());
} else {
- RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext);
+ if (forwardToDestination) {
+ request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
+ } else {
+ RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext);
+ }
}
}
@@ -44,7 +51,8 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
*
* @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp".
*/
- public void setDefaultTargetUrl(String defaultFailureUrl) {
+ public void setDefaultFailureUrl(String defaultFailureUrl) {
+ Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultFailureUrl));
this.defaultFailureUrl = defaultFailureUrl;
}
diff --git a/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java
index eaf15f9c55..25ba563f22 100644
--- a/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java
+++ b/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java
@@ -26,6 +26,7 @@ import org.springframework.security.util.TextUtils;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@@ -53,7 +54,7 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
//~ Methods ========================================================================================================
- public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {
+ public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
String username = obtainUsername(request);
String password = obtainPassword(request);
diff --git a/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPoint.java b/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPoint.java
index fa34febf56..15333d6cc3 100644
--- a/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPoint.java
+++ b/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPoint.java
@@ -24,6 +24,7 @@ import org.springframework.security.util.PortMapperImpl;
import org.springframework.security.util.PortResolver;
import org.springframework.security.util.PortResolverImpl;
import org.springframework.security.util.RedirectUrlBuilder;
+import org.springframework.security.util.UrlUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -31,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
import java.io.IOException;
@@ -79,7 +81,8 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationE
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
- Assert.hasLength(loginFormUrl, "loginFormUrl must be specified");
+ Assert.isTrue(StringUtils.hasText(loginFormUrl) && UrlUtils.isValidRedirectUrl(loginFormUrl),
+ "loginFormUrl must be specified and must be a valid redirect URL");
Assert.notNull(portMapper, "portMapper must be specified");
Assert.notNull(portResolver, "portResolver must be specified");
}
@@ -117,7 +120,7 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationE
if (redirectUrl == null) {
String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
-
+
if (logger.isDebugEnabled()) {
logger.debug("Server side forward to: " + loginForm);
}
@@ -246,7 +249,7 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationE
*/
public void setServerSideRedirect(boolean serverSideRedirect) {
this.serverSideRedirect = serverSideRedirect;
- }
+ }
protected boolean isServerSideRedirect() {
return serverSideRedirect;
diff --git a/core/src/main/java/org/springframework/security/util/UrlUtils.java b/core/src/main/java/org/springframework/security/util/UrlUtils.java
index b4be3056f9..7ad6ea0524 100644
--- a/core/src/main/java/org/springframework/security/util/UrlUtils.java
+++ b/core/src/main/java/org/springframework/security/util/UrlUtils.java
@@ -15,13 +15,11 @@
package org.springframework.security.util;
-import org.springframework.security.intercept.web.FilterInvocation;
-
-import org.springframework.security.ui.savedrequest.SavedRequest;
-import org.springframework.util.StringUtils;
-
import javax.servlet.http.HttpServletRequest;
+import org.springframework.security.intercept.web.FilterInvocation;
+import org.springframework.security.ui.savedrequest.SavedRequest;
+
/**
* Provides static methods for composing URLs.Placed into a separate class for visibility, so that changes to
@@ -102,8 +100,11 @@ public final class UrlUtils {
return buildRequestUrl(sr.getServletPath(), sr.getRequestURI(), sr.getContextPath(), sr.getPathInfo(),
sr.getQueryString());
}
-
+
+ /**
+ * Returns true if the supplied URL starts with a "/" or "http".
+ */
public static boolean isValidRedirectUrl(String url) {
- return !StringUtils.hasText(url) || url.startsWith("/") || url.toLowerCase().startsWith("http");
+ return url.startsWith("/") || url.toLowerCase().startsWith("http");
}
}
diff --git a/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java b/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java
index 49f68bcfa1..d03e89b76b 100644
--- a/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java
+++ b/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java
@@ -55,6 +55,7 @@ import org.springframework.security.util.PortResolverImpl;
*/
public class AbstractProcessingFilterTests extends TestCase {
SavedRequestAwareAuthenticationSuccessHandler successHandler;
+ SimpleUrlAuthenticationFailureHandler failureHandler;
//~ Methods ========================================================================================================
private MockHttpServletRequest createMockRequest() {
@@ -102,6 +103,8 @@ public class AbstractProcessingFilterTests extends TestCase {
super.setUp();
successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setDefaultTargetUrl("/logged_in.jsp");
+ failureHandler = new SimpleUrlAuthenticationFailureHandler();
+ failureHandler.setDefaultFailureUrl("/failed.jsp");
SecurityContextHolder.clearContext();
}
@@ -133,7 +136,7 @@ public class AbstractProcessingFilterTests extends TestCase {
// Setup our test object, to deny access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
- filter.setAuthenticationFailureUrl("/failed.jsp");
+ filter.setFailureHandler(failureHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
@@ -143,11 +146,11 @@ public class AbstractProcessingFilterTests extends TestCase {
//Prepare again, this time using the exception mapping
filter = new MockAbstractProcessingFilter(new AccountExpiredException("You're account is expired"));
- filter.setAuthenticationFailureUrl("/failed.jsp");
-
- Properties exceptionMappings = filter.getExceptionMappings();
+ ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
+ filter.setFailureHandler(failureHandler);
+ Properties exceptionMappings = new Properties();
exceptionMappings.setProperty(AccountExpiredException.class.getName(), "/accountExpired.jsp");
- filter.setExceptionMappings(exceptionMappings);
+ failureHandler.setExceptionMappings(exceptionMappings);
response = new MockHttpServletResponse();
// Test
@@ -186,7 +189,6 @@ public class AbstractProcessingFilterTests extends TestCase {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setFilterProcessesUrl("/p");
- filter.setAuthenticationFailureUrl("/fail");
filter.afterPropertiesSet();
assertNotNull(filter.getRememberMeServices());
@@ -194,7 +196,6 @@ public class AbstractProcessingFilterTests extends TestCase {
assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass());
assertTrue(filter.getAuthenticationManager() != null);
assertEquals("/p", filter.getFilterProcessesUrl());
- assertEquals("/fail", filter.getAuthenticationFailureUrl());
}
public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl() throws Exception {
@@ -234,7 +235,7 @@ public class AbstractProcessingFilterTests extends TestCase {
filter.setFilterProcessesUrl("/j_mock_post");
filter.setSuccessHandler(successHandler);
- filter.setAuthenticationFailureUrl("/failure.jsp");
+ filter.setFailureHandler(failureHandler);
filter.setAuthenticationManager(new MockAuthenticationManager(true));
filter.afterPropertiesSet();
@@ -249,7 +250,7 @@ public class AbstractProcessingFilterTests extends TestCase {
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
- filter.setAuthenticationFailureUrl("/failed.jsp");
+ filter.setFailureHandler(failureHandler);
successHandler.setDefaultTargetUrl("/");
filter.setSuccessHandler(successHandler);
filter.setFilterProcessesUrl("/j_spring_security_check");
@@ -264,7 +265,7 @@ public class AbstractProcessingFilterTests extends TestCase {
public void testStartupDetectsInvalidFilterProcessesUrl() throws Exception {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
- filter.setAuthenticationFailureUrl("/failed.jsp");
+ filter.setFailureHandler(failureHandler);
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setSuccessHandler(successHandler);
filter.setFilterProcessesUrl(null);
@@ -308,7 +309,7 @@ public class AbstractProcessingFilterTests extends TestCase {
// Setup our test object, to deny access
filter = new MockAbstractProcessingFilter(false);
filter.setFilterProcessesUrl("/j_mock_post");
- filter.setAuthenticationFailureUrl("/failed.jsp");
+ filter.setFailureHandler(failureHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
@@ -468,7 +469,7 @@ public class AbstractProcessingFilterTests extends TestCase {
// Reject authentication, so exception would normally be stored in session
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
filter.setAllowSessionCreation(false);
- filter.setAuthenticationFailureUrl("/");
+ filter.setFailureHandler(failureHandler);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setSuccessHandler(successHandler);
@@ -509,8 +510,9 @@ public class AbstractProcessingFilterTests extends TestCase {
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setSuccessHandler(successHandler);
- filter.setAuthenticationFailureUrl("/error");
- filter.setServerSideRedirect(true);
+ filter.setFailureHandler(failureHandler);
+ failureHandler.setForwardToDestination(true);
+ failureHandler.setDefaultFailureUrl("/error");
executeFilterInContainerSimulator(config, filter, request, response, chain);
@@ -532,7 +534,7 @@ public class AbstractProcessingFilterTests extends TestCase {
filter.setSuccessHandler(successHandler);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
successHandler.setTargetUrlParameter("targetUrl");
- filter.setAuthenticationFailureUrl("/error");
+ filter.setFailureHandler(failureHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
@@ -561,7 +563,7 @@ public class AbstractProcessingFilterTests extends TestCase {
private MockAbstractProcessingFilter() {
}
- public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {
+ public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (grantAccess) {
return new UsernamePasswordAuthenticationToken("test", "test", AuthorityUtils.createAuthorityList("TEST"));
} else {
diff --git a/core/src/test/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java b/core/src/test/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java
index 3d95ca4eb7..008feaafad 100644
--- a/core/src/test/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java
+++ b/core/src/test/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java
@@ -47,7 +47,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertEquals("loginFormUrl must be specified", expected.getMessage());
}
}
@@ -60,7 +59,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertEquals("portMapper must be specified", expected.getMessage());
}
}
@@ -73,7 +71,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertEquals("portResolver must be specified", expected.getMessage());
}
}
@@ -126,7 +123,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
PortMapperImpl portMapper = new PortMapperImpl();
- Map map = new HashMap();
+ Map
+ * The OpenID authentication involves two stages.
+ *
+ * Submission of OpenID identity
+ *
+ * The user's OpenID identity is submitted via a login form, just as it would be for a normal form login. At this stage
+ * the filter will extract the identity from the submitted request (by default, the parameter is called
+ * j_username, as it is for form login. It then passes the identity to the configured OpenIDConsumer,
+ * which returns the URL to which the request should be redirected for authentication. A "return_to" URL is also supplied,
+ * which matches the URL processed by this filter, to allow the filter to handle the request once the user has
+ * been successfully authenticated. The OpenID server will then authenticate the user and redirect back to the
+ * application.
+ *
+ * Processing the Redirect from the OpenID Server
+ *
+ * Once the user has been authenticated externally, the redirected request will be passed to the OpenIDConsumer
+ * again for validation. The returned OpenIDAuthentication will be passed to the AuthenticationManager
+ * where it should (normally) be processed by an OpenIDAuthenticationProvider in order to load the authorities
+ * for the user.
+ *
+ * @author Robin Bramley
* @author Ray Krueger
+ * @author Luke Taylor
* @version $Id$
* @since 2.0
+ * @see OpenIDAuthenticationProvider
*/
public class OpenIDAuthenticationProcessingFilter extends AbstractProcessingFilter {
//~ Static fields/initializers =====================================================================================
- private static final Log log = LogFactory.getLog(OpenIDAuthenticationProcessingFilter.class);
public static final String DEFAULT_CLAIMED_IDENTITY_FIELD = "j_username";
//~ Instance fields ================================================================================================
private OpenIDConsumer consumer;
private String claimedIdentityFieldName = DEFAULT_CLAIMED_IDENTITY_FIELD;
- private Map realmMapping = new HashMap();
+ private Map
+ *
+ */
+ @Override
+ public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
+ throws AuthenticationException, IOException {
OpenIDAuthenticationToken token;
- String identity = req.getParameter("openid.identity");
+ String identity = request.getParameter("openid.identity");
if (!StringUtils.hasText(identity)) {
+ String claimedIdentity = obtainUsername(request);
// Make the username available to the view
- String username = obtainUsername(req);
- setLastUsername(username, req);
- throw new OpenIDAuthenticationRequiredException("External Authentication Required", username);
+ setLastUsername(claimedIdentity, request);
+
+ try {
+ String returnToUrl = buildReturnToUrl(request);
+ String realm = lookupRealm(returnToUrl);
+ String openIdUrl = consumer.beginConsumption(request, claimedIdentity, returnToUrl, realm);
+ if (logger.isDebugEnabled()) {
+ logger.debug("return_to is '" + returnToUrl + "', realm is '" + realm + "'");
+ logger.debug("Redirecting to " + openIdUrl);
+ }
+ response.sendRedirect(openIdUrl);
+
+ // Indicate to parent class that authentication is continuing.
+ return null;
+ } catch (OpenIDConsumerException e) {
+ logger.debug("Failed to consume claimedIdentity: " + claimedIdentity, e);
+ throw new AuthenticationServiceException("Unable to process claimed identity '" + claimedIdentity + "'");
+ }
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Supplied OpenID identity is " + identity);
}
try {
- token = consumer.endConsumption(req);
+ token = consumer.endConsumption(request);
} catch (OpenIDConsumerException oice) {
throw new AuthenticationServiceException("Consumer error", oice);
}
- token.setDetails(authenticationDetailsSource.buildDetails(req));
+ token.setDetails(authenticationDetailsSource.buildDetails(request));
- // delegate to the auth provider
+ // delegate to the authentication provider
Authentication authentication = this.getAuthenticationManager().authenticate(token);
if (authentication.isAuthenticated()) {
- setLastUsername(token.getIdentityUrl(), req);
+ setLastUsername(token.getIdentityUrl(), request);
}
return authentication;
@@ -104,28 +158,8 @@ public class OpenIDAuthenticationProcessingFilter extends AbstractProcessingFilt
}
}
- protected String determineFailureUrl(HttpServletRequest request, AuthenticationException failed) {
- if (failed instanceof OpenIDAuthenticationRequiredException) {
- OpenIDAuthenticationRequiredException openIdRequiredException = (OpenIDAuthenticationRequiredException) failed;
- String claimedIdentity = openIdRequiredException.getClaimedIdentity();
-
- if (StringUtils.hasText(claimedIdentity)) {
- try {
- String returnToUrl = buildReturnToUrl(request);
- String realm = lookupRealm(returnToUrl);
- return consumer.beginConsumption(request, claimedIdentity, returnToUrl, realm);
- } catch (OpenIDConsumerException e) {
- log.error("Unable to consume claimedIdentity [" + claimedIdentity + "]", e);
- }
- }
- }
-
- return super.determineFailureUrl(request, failed);
- }
-
protected String lookupRealm(String returnToUrl) {
-
- String mapping = (String) realmMapping.get(returnToUrl);
+ String mapping = realmMapping.get(returnToUrl);
if (mapping == null) {
try {
@@ -140,61 +174,52 @@ public class OpenIDAuthenticationProcessingFilter extends AbstractProcessingFilt
.append("/");
mapping = realmBuffer.toString();
} catch (MalformedURLException e) {
- log.warn("returnToUrl was not a valid URL: [" + returnToUrl + "]", e);
+ logger.warn("returnToUrl was not a valid URL: [" + returnToUrl + "]", e);
}
}
return mapping;
}
+ /**
+ * Builds the return_to URL that will be sent to the OpenID service provider.
+ * By default returns the URL of the current request.
+ *
+ * @param request the current request which is being processed by this filter
+ * @return The return_to URL.
+ */
protected String buildReturnToUrl(HttpServletRequest request) {
return request.getRequestURL().toString();
}
- public String getClaimedIdentityFieldName() {
- return claimedIdentityFieldName;
- }
-
- public OpenIDConsumer getConsumer() {
- return consumer;
- }
-
- public String getDefaultFilterProcessesUrl() {
- return "/j_spring_openid_security_check";
- }
-
- protected boolean isAuthenticated(HttpServletRequest request) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-
- return (auth != null) && auth.isAuthenticated();
- }
-
/**
- * The OpenIdAuthenticationProcessingFilter will ignore the request coming in if this method returns false.
- * The default functionality checks if the request scheme starts with http.
This method should be overridden in subclasses that wish to consider a different strategy
- *
- * @param request HttpServletRequest we're processing
- * @return true if this request is determined to be an OpenID request.
+ * Reads the claimedIdentityFieldName from the submitted request.
*/
- protected boolean isOpenIdRequest(HttpServletRequest request) {
- String username = obtainUsername(request);
- return (StringUtils.hasText(username)) && username.toLowerCase().startsWith("http");
- }
-
protected String obtainUsername(HttpServletRequest req) {
return req.getParameter(claimedIdentityFieldName);
}
- protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException failed) throws IOException {
- if (failed instanceof OpenIDAuthenticationRequiredException) {
- OpenIDAuthenticationRequiredException openIdAuthenticationRequiredException = (OpenIDAuthenticationRequiredException) failed;
- request.setAttribute(OpenIDAuthenticationRequiredException.class.getName(),
- openIdAuthenticationRequiredException.getClaimedIdentity());
- }
+ /**
+ * Maps the return_to url to a realm, for example:
+ *
+ * http://www.example.com/j_spring_openid_security_check -> http://www.example.com/realm
+ *
+ * If no mapping is provided then the returnToUrl will be parsed to extract the protocol, hostname and port followed
+ * by a trailing slash.
+ * This means that http://www.example.com/j_spring_openid_security_check will automatically become
+ * http://www.example.com:80/
+ *
+ * @param realmMapping containing returnToUrl -> realm mappings
+ */
+ public void setRealmMapping(Map
- * For example http://www.example.com/j_spring_openid_security_check -> http://www.example.com/realm
- * If no mapping is provided then the returnToUrl will be parsed to extract the protocol, hostname and port followed
- * by a trailing slash.
- * This means that http://www.example.com/j_spring_openid_security_check will automatically
- * become http://www.example.com:80/
- *
- * @return Map containing returnToUrl -> realm mappings
- */
- public Map getRealmMapping() {
- return realmMapping;
- }
-
- /**
- * Maps the return_to url to a realm.
- * For example http://www.example.com/j_spring_openid_security_check -> http://www.example.com/realm
- * If no mapping is provided then the returnToUrl will be parsed to extract the protocol, hostname and port followed
- * by a trailing slash.
- * This means that http://www.example.com/j_spring_openid_security_check will automatically
- * become http://www.example.com:80/
- *
- * @param realmMapping containing returnToUrl -> realm mappings
- */
- public void setRealmMapping(Map realmMapping) {
- this.realmMapping = realmMapping;
- }
}
diff --git a/openid/src/main/java/org/springframework/security/ui/openid/OpenIDAuthenticationRequiredException.java b/openid/src/main/java/org/springframework/security/ui/openid/OpenIDAuthenticationRequiredException.java
deleted file mode 100644
index d5115832ff..0000000000
--- a/openid/src/main/java/org/springframework/security/ui/openid/OpenIDAuthenticationRequiredException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.security.ui.openid;
-
-import org.springframework.security.AuthenticationException;
-
-/**
- * @author Ray Krueger
- */
-public class OpenIDAuthenticationRequiredException extends AuthenticationException {
-
- private final String claimedIdentity;
-
- public OpenIDAuthenticationRequiredException(String msg, String claimedIdentity) {
- super(msg);
- this.claimedIdentity = claimedIdentity;
- }
-
- public String getClaimedIdentity() {
- return claimedIdentity;
- }
-}
diff --git a/openid/src/test/java/org/springframework/security/ui/openid/OpenIDAuthenticationProcessingFilterTests.java b/openid/src/test/java/org/springframework/security/ui/openid/OpenIDAuthenticationProcessingFilterTests.java
index f5ab4495fa..b40796d989 100644
--- a/openid/src/test/java/org/springframework/security/ui/openid/OpenIDAuthenticationProcessingFilterTests.java
+++ b/openid/src/test/java/org/springframework/security/ui/openid/OpenIDAuthenticationProcessingFilterTests.java
@@ -29,16 +29,6 @@ public class OpenIDAuthenticationProcessingFilterTests extends TestCase {
filter.afterPropertiesSet();
}
- public void testNoIdentityCausesException() throws Exception {
- try {
- MockHttpServletRequest req = new MockHttpServletRequest();
- filter.attemptAuthentication(req);
- fail("OpenIDAuthenticationRequiredException expected, no openid.identity parameter");
- } catch (OpenIDAuthenticationRequiredException e) {
- //cool
- }
- }
-
public void testFilterOperation() throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest("GET", REQUEST_PATH);
MockHttpServletResponse response = new MockHttpServletResponse();
diff --git a/samples/openid/src/main/webapp/WEB-INF/classes/log4j.properties b/samples/openid/src/main/webapp/WEB-INF/classes/log4j.properties
index 2f7890f02e..ddd6feb06c 100644
--- a/samples/openid/src/main/webapp/WEB-INF/classes/log4j.properties
+++ b/samples/openid/src/main/webapp/WEB-INF/classes/log4j.properties
@@ -1,20 +1,12 @@
# Global logging configuration
-log4j.rootLogger=INFO, stdout, fileout
+log4j.rootLogger=INFO, stdout
-log4j.logger.org.springframework.security=DEBUG, stdout, fileout
+log4j.logger.org.springframework.security=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.conversionPattern=[%p,%c{1},%t] %m%n
-
-# Rolling log file output...
-log4j.appender.fileout=org.apache.log4j.RollingFileAppender
-log4j.appender.fileout.File=spring-security-openid.log
-#log4j.appender.fileout.File=${webapp.root}/WEB-INF/log4j.log
-log4j.appender.fileout.MaxFileSize=1024KB
-log4j.appender.fileout.MaxBackupIndex=1
-log4j.appender.fileout.layout=org.apache.log4j.PatternLayout
-log4j.appender.fileout.layout.conversionPattern=%d{ABSOLUTE} %5p %c{1},%t:%L - %m%n
+log4j.appender.stdout.layout.conversionPattern=[%p,%c{1}] %m%n
+
diff --git a/samples/openid/src/main/webapp/WEB-INF/web.xml b/samples/openid/src/main/webapp/WEB-INF/web.xml
index b203f61cfc..9cc9e28f00 100644
--- a/samples/openid/src/main/webapp/WEB-INF/web.xml
+++ b/samples/openid/src/main/webapp/WEB-INF/web.xml
@@ -12,20 +12,25 @@