SEC-1160: Renaming of authentication filters and entry points and associated doc changes
This commit is contained in:
@@ -38,7 +38,7 @@ public interface AuthenticationEntryPoint {
|
||||
* Commences an authentication scheme.
|
||||
* <p>
|
||||
* <code>ExceptionTranslationFilter</code> will populate the <code>HttpSession</code> attribute named
|
||||
* <code>AbstractProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY</code> with the requested target URL before
|
||||
* <code>AbstractAuthenticationProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY</code> with the requested target URL before
|
||||
* calling this method.
|
||||
* <p>
|
||||
* Implementations should modify the headers on the <code>ServletResponse</code> as necessary to
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ public class ExceptionTranslationFilter extends SpringSecurityFilter implements
|
||||
SavedRequest savedRequest = new SavedRequest(request, portResolver);
|
||||
|
||||
if (createSessionAllowed || request.getSession(false) != null) {
|
||||
// Store the HTTP request itself. Used by AbstractProcessingFilter
|
||||
// Store the HTTP request itself. Used by AbstractAuthenticationProcessingFilter
|
||||
// for redirection after successful authentication (SEC-29)
|
||||
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
|
||||
logger.debug("SavedRequest added to Session: " + savedRequest);
|
||||
|
||||
+439
@@ -0,0 +1,439 @@
|
||||
/* 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.web.authentication;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.concurrent.SessionRegistry;
|
||||
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.SpringSecurityFilter;
|
||||
import org.springframework.security.web.session.SessionUtils;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstract processor of browser-based HTTP-based authentication requests.
|
||||
*
|
||||
* <h3>Authentication Process</h3>
|
||||
*
|
||||
* The filter requires that you set the <tt>authenticationManager</tt> property. An <tt>AuthenticationManager</tt> is
|
||||
* required to process the authentication request tokens created by implementing classes.
|
||||
* <p>
|
||||
* This filter will intercept a request and attempt to perform authentication from that request if
|
||||
* the request URL matches the value of the <tt>filterProcessesUrl</tt> property. This behaviour can modified by
|
||||
* overriding the method {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}.
|
||||
* <p>
|
||||
* Authentication is performed by the {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse)
|
||||
* attemptAuthentication} method, which must be implemented by subclasses.
|
||||
*
|
||||
* <h4>Authentication Success</h4>
|
||||
*
|
||||
* If authentication is successful, the resulting {@link Authentication} object will be placed into the
|
||||
* <code>SecurityContext</code> for the current thread, which is guaranteed to have already been created by an earlier
|
||||
* filter. The configured {@link #setAuthenticationSuccessHandler(AuthenticationSuccessHandler) AuthenticationSuccessHandler} will
|
||||
* then be called to take the redirect to the appropriate destination after a successful login. The default behaviour
|
||||
* is implemented in a {@link SavedRequestAwareAuthenticationSuccessHandler} which will make use of any
|
||||
* <tt>SavedRequest</tt> set by the <tt>ExceptionTranslationFilter</tt> and redirect the user to the URL contained
|
||||
* therein. Otherwise it will redirect to the webapp root "/". You can customize this behaviour by injecting a
|
||||
* differently configured instance of this class, or by using a different implementation.
|
||||
* <p>
|
||||
* See the {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* successfulAuthentication} method for more information.
|
||||
*
|
||||
* <h4>Authentication Failure</h4>
|
||||
*
|
||||
* If authentication fails, the resulting <tt>AuthenticationException</tt> will be placed into the <tt>HttpSession</tt>
|
||||
* with the attribute defined by {@link #SPRING_SECURITY_LAST_EXCEPTION_KEY}. It will then delegate to the configured
|
||||
* {@link AuthenticationFailureHandler} to allow the failure information to be conveyed to the client.
|
||||
* The default implementation is {@link SimpleUrlAuthenticationFailureHandler}, which sends a 401 error code to the
|
||||
* client. It may also be configured with a failure URL as an alternative. Again you can inject whatever
|
||||
* behaviour you require here.
|
||||
*
|
||||
* <h4>Event Publication</h4>
|
||||
*
|
||||
* If authentication is successful, an
|
||||
* {@link org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
|
||||
* InteractiveAuthenticationSuccessEvent} will be published via the application context. No events will be published if
|
||||
* authentication was unsuccessful, because this would generally be recorded via an
|
||||
* <tt>AuthenticationManager</tt>-specific application event.
|
||||
* <p>
|
||||
* The filter has an optional attribute <tt>invalidateSessionOnSuccessfulAuthentication</tt> that will invalidate
|
||||
* the current session on successful authentication. This is to protect against session fixation attacks (see
|
||||
* <a href="http://en.wikipedia.org/wiki/Session_fixation">this Wikipedia article</a> for more information).
|
||||
* The behaviour is turned off by default. Additionally there is a property <tt>migrateInvalidatedSessionAttributes</tt>
|
||||
* which tells if on session invalidation we are to migrate all session attributes from the old session to a newly
|
||||
* created one. This is turned on by default, but not used unless <tt>invalidateSessionOnSuccessfulAuthentication</tt>
|
||||
* is true. If you are using this feature in combination with concurrent session control, you should set the
|
||||
* <tt>sessionRegistry</tt> property to make sure that the session information is updated consistently.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAuthenticationProcessingFilter extends SpringSecurityFilter implements InitializingBean,
|
||||
ApplicationEventPublisherAware, MessageSourceAware {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = "SPRING_SECURITY_LAST_EXCEPTION";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected ApplicationEventPublisher eventPublisher;
|
||||
protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||
private AuthenticationManager authenticationManager;
|
||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
|
||||
/*
|
||||
* Delay use of NullRememberMeServices until initialization so that namespace has a chance to inject
|
||||
* the RememberMeServices implementation into custom implementations.
|
||||
*/
|
||||
private RememberMeServices rememberMeServices = null;
|
||||
|
||||
/**
|
||||
* The URL destination that this filter intercepts and processes (usually
|
||||
* something like <code>/j_spring_security_check</code>)
|
||||
*/
|
||||
private String filterProcessesUrl;
|
||||
|
||||
private boolean continueChainBeforeSuccessfulAuthentication = false;
|
||||
|
||||
/**
|
||||
* Tells if we on successful authentication should invalidate the
|
||||
* current session. This is a common guard against session fixation attacks.
|
||||
* Defaults to <code>false</code>.
|
||||
*/
|
||||
private boolean invalidateSessionOnSuccessfulAuthentication = false;
|
||||
|
||||
/**
|
||||
* If {@link #invalidateSessionOnSuccessfulAuthentication} is true, this
|
||||
* flag indicates that the session attributes of the session to be invalidated
|
||||
* are to be migrated to the new session. Defaults to <code>true</code> since
|
||||
* nothing will happen unless {@link #invalidateSessionOnSuccessfulAuthentication}
|
||||
* is true.
|
||||
*/
|
||||
private boolean migrateInvalidatedSessionAttributes = true;
|
||||
|
||||
private boolean allowSessionCreation = true;
|
||||
|
||||
private SessionRegistry sessionRegistry;
|
||||
|
||||
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||
private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>.
|
||||
*/
|
||||
protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
|
||||
this.filterProcessesUrl = defaultFilterProcessesUrl;
|
||||
}
|
||||
|
||||
//~ 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.notNull(authenticationManager, "authenticationManager must be specified");
|
||||
|
||||
if (rememberMeServices == null) {
|
||||
rememberMeServices = new NullRememberMeServices();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* <ol>
|
||||
* <li>An <tt>Authentication</tt> object is returned.
|
||||
* The {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* successfulAuthentication} method will be invoked</li>
|
||||
* <li>An <tt>AuthenticationException</tt> occurs during authentication.
|
||||
* The {@link #unSuccessfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* unSuccessfulAuthentication} method will be invoked</li>
|
||||
* <li>Null is returned, indicating that the authentication process is incomplete.
|
||||
* The method will then return immediately, assuming that the subclass has done any necessary work (such as
|
||||
* redirects) to continue the authentication process. The assumption is that a later request will be received
|
||||
* by this method where the returned <tt>Authentication</tt> object is not null.
|
||||
* </ol>
|
||||
*/
|
||||
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
if (!requiresAuthentication(request, response)) {
|
||||
chain.doFilter(request, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Request is to process authentication");
|
||||
}
|
||||
|
||||
Authentication authResult;
|
||||
|
||||
try {
|
||||
authResult = attemptAuthentication(request, response);
|
||||
if (authResult == null) {
|
||||
// return immediately as subclass has indicated that it hasn't completed authentication
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (AuthenticationException failed) {
|
||||
// Authentication failed
|
||||
unsuccessfulAuthentication(request, response, failed);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Authentication success
|
||||
if (continueChainBeforeSuccessfulAuthentication) {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
successfulAuthentication(request, response, authResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this filter should attempt to process a login request for the current invocation.
|
||||
* <p>
|
||||
* It strips any parameters from the "path" section of the request URL (such
|
||||
* as the jsessionid parameter in
|
||||
* <em>http://host/myapp/index.html;jsessionid=blah</em>) before matching
|
||||
* against the <code>filterProcessesUrl</code> property.
|
||||
* <p>
|
||||
* Subclasses may override for special requirements, such as Tapestry integration.
|
||||
*
|
||||
* @return <code>true</code> if the filter should attempt authentication, <code>false</code> otherwise.
|
||||
*/
|
||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||
String uri = request.getRequestURI();
|
||||
int pathParamIndex = uri.indexOf(';');
|
||||
|
||||
if (pathParamIndex > 0) {
|
||||
// strip everything after the first semi-colon
|
||||
uri = uri.substring(0, pathParamIndex);
|
||||
}
|
||||
|
||||
if ("".equals(request.getContextPath())) {
|
||||
return uri.endsWith(filterProcessesUrl);
|
||||
}
|
||||
|
||||
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs actual authentication.
|
||||
* <p>
|
||||
* The implementation should do one of the following:
|
||||
* <ol>
|
||||
* <li>Return a populated authentication token for the authenticated user, indicating successful authentication</li>
|
||||
* <li>Return null, indicating that the authentication process is still in progress. Before returning, the
|
||||
* implementation should perform any additional work required to complete the process.</li>
|
||||
* <li>Throw an <tt>AuthenticationException</tt> if the authentication process fails</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param request from which to extract parameters and perform the authentication
|
||||
* @param response the response, which may be needed if the implementation has to do a redirect as part of a
|
||||
* multi-stage authentication process (such as OpenID).
|
||||
*
|
||||
* @return the authenticated user token, or null if authentication is incomplete.
|
||||
*
|
||||
* @throws AuthenticationException if authentication fails.
|
||||
*/
|
||||
public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException, IOException, ServletException;
|
||||
|
||||
/**
|
||||
* Default behaviour for successful authentication.
|
||||
* <ol>
|
||||
* <li>Sets the successful <tt>Authentication</tt> object on the {@link SecurityContextHolder}</li>
|
||||
* <li>Performs any configured session migration behaviour</li>
|
||||
* <li>Informs the configured <tt>RememberMeServices</tt> of the successful login</li>
|
||||
* <li>Fires an {@link InteractiveAuthenticationSuccessEvent} via the configured
|
||||
* <tt>ApplicationEventPublisher</tt></li>
|
||||
* <li>Delegates additional behaviour to the {@link AuthenticationSuccessHandler}.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param authResult the object returned from the <tt>attemptAuthentication</tt> method.
|
||||
*/
|
||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authResult) throws IOException, ServletException {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
|
||||
}
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(authResult);
|
||||
|
||||
if (invalidateSessionOnSuccessfulAuthentication) {
|
||||
SessionUtils.startNewSessionIfRequired(request, migrateInvalidatedSessionAttributes, sessionRegistry);
|
||||
}
|
||||
|
||||
rememberMeServices.loginSuccess(request, response, authResult);
|
||||
|
||||
// Fire event
|
||||
if (this.eventPublisher != null) {
|
||||
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
|
||||
}
|
||||
|
||||
successHandler.onAuthenticationSuccess(request, response, authResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default behaviour for unsuccessful authentication.
|
||||
* <ol>
|
||||
* <li>Clears the {@link SecurityContextHolder}</li>
|
||||
* <li>Stores the exception in the session (if it exists or <tt>allowSesssionCreation</tt> is set to <tt>true</tt>)</li>
|
||||
* <li>Informs the configured <tt>RememberMeServices</tt> of the failed login</li>
|
||||
* <li>Delegates additional behaviour to the {@link AuthenticationFailureHandler}.</li>
|
||||
* </ol>
|
||||
*/
|
||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException failed) throws IOException, ServletException {
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request failed: " + failed.toString());
|
||||
logger.debug("Updated SecurityContextHolder to contain null Authentication");
|
||||
logger.debug("Delegating to authentication failure handler" + failureHandler);
|
||||
}
|
||||
|
||||
try {
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null || allowSessionCreation) {
|
||||
request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||
}
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
|
||||
rememberMeServices.loginFail(request, response);
|
||||
|
||||
failureHandler.onAuthenticationFailure(request, response, failed);
|
||||
}
|
||||
|
||||
protected AuthenticationManager getAuthenticationManager() {
|
||||
return authenticationManager;
|
||||
}
|
||||
|
||||
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
|
||||
public String getFilterProcessesUrl() {
|
||||
return filterProcessesUrl;
|
||||
}
|
||||
|
||||
public void setFilterProcessesUrl(String filterProcessesUrl) {
|
||||
this.filterProcessesUrl = filterProcessesUrl;
|
||||
}
|
||||
|
||||
public RememberMeServices getRememberMeServices() {
|
||||
return rememberMeServices;
|
||||
}
|
||||
|
||||
public void setRememberMeServices(RememberMeServices rememberMeServices) {
|
||||
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 <code>false</code>.
|
||||
*/
|
||||
public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
|
||||
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
|
||||
}
|
||||
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
|
||||
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
|
||||
this.authenticationDetailsSource = authenticationDetailsSource;
|
||||
}
|
||||
|
||||
public void setMessageSource(MessageSource messageSource) {
|
||||
this.messages = new MessageSourceAccessor(messageSource);
|
||||
}
|
||||
|
||||
public void setInvalidateSessionOnSuccessfulAuthentication(boolean invalidateSessionOnSuccessfulAuthentication) {
|
||||
this.invalidateSessionOnSuccessfulAuthentication = invalidateSessionOnSuccessfulAuthentication;
|
||||
}
|
||||
|
||||
public void setMigrateInvalidatedSessionAttributes(boolean migrateInvalidatedSessionAttributes) {
|
||||
this.migrateInvalidatedSessionAttributes = migrateInvalidatedSessionAttributes;
|
||||
}
|
||||
|
||||
public AuthenticationDetailsSource getAuthenticationDetailsSource() {
|
||||
// Required due to SEC-310
|
||||
return authenticationDetailsSource;
|
||||
}
|
||||
|
||||
protected boolean getAllowSessionCreation() {
|
||||
return allowSessionCreation;
|
||||
}
|
||||
|
||||
public void setAllowSessionCreation(boolean allowSessionCreation) {
|
||||
this.allowSessionCreation = allowSessionCreation;
|
||||
}
|
||||
|
||||
/**
|
||||
* The session registry needs to be set if session fixation attack protection is in use (and concurrent
|
||||
* session control is enabled).
|
||||
*/
|
||||
public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the strategy used to handle a successful authentication.
|
||||
* By default a {@link SavedRequestAwareAuthenticationSuccessHandler} is used.
|
||||
*/
|
||||
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
|
||||
Assert.notNull(successHandler, "successHandler cannot be null");
|
||||
this.successHandler = successHandler;
|
||||
}
|
||||
|
||||
public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
|
||||
Assert.notNull(failureHandler, "failureHandler cannot be null");
|
||||
this.failureHandler = failureHandler;
|
||||
}
|
||||
}
|
||||
+7
-428
@@ -1,439 +1,18 @@
|
||||
/* 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.web.authentication;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.concurrent.SessionRegistry;
|
||||
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.SpringSecurityFilter;
|
||||
import org.springframework.security.web.session.SessionUtils;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstract processor of browser-based HTTP-based authentication requests.
|
||||
*
|
||||
* <h3>Authentication Process</h3>
|
||||
*
|
||||
* The filter requires that you set the <tt>authenticationManager</tt> property. An <tt>AuthenticationManager</tt> is
|
||||
* required to process the authentication request tokens created by implementing classes.
|
||||
* Renamed class, retained for backwards compatibility.
|
||||
* <p>
|
||||
* This filter will intercept a request and attempt to perform authentication from that request if
|
||||
* the request URL matches the value of the <tt>filterProcessesUrl</tt> property. This behaviour can modified by
|
||||
* overriding the method {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}.
|
||||
* <p>
|
||||
* Authentication is performed by the {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse)
|
||||
* attemptAuthentication} method, which must be implemented by subclasses.
|
||||
* See {@link AbstractAuthenticationProcessingFilter}.
|
||||
*
|
||||
* <h4>Authentication Success</h4>
|
||||
*
|
||||
* If authentication is successful, the resulting {@link Authentication} object will be placed into the
|
||||
* <code>SecurityContext</code> for the current thread, which is guaranteed to have already been created by an earlier
|
||||
* filter. The configured {@link #setAuthenticationSuccessHandler(AuthenticationSuccessHandler) AuthenticationSuccessHandler} will
|
||||
* then be called to take the redirect to the appropriate destination after a successful login. The default behaviour
|
||||
* is implemented in a {@link SavedRequestAwareAuthenticationSuccessHandler} which will make use of any
|
||||
* <tt>SavedRequest</tt> set by the <tt>ExceptionTranslationFilter</tt> and redirect the user to the URL contained
|
||||
* therein. Otherwise it will redirect to the webapp root "/". You can customize this behaviour by injecting a
|
||||
* differently configured instance of this class, or by using a different implementation.
|
||||
* <p>
|
||||
* See the {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* successfulAuthentication} method for more information.
|
||||
*
|
||||
* <h4>Authentication Failure</h4>
|
||||
*
|
||||
* If authentication fails, the resulting <tt>AuthenticationException</tt> will be placed into the <tt>HttpSession</tt>
|
||||
* with the attribute defined by {@link #SPRING_SECURITY_LAST_EXCEPTION_KEY}. It will then delegate to the configured
|
||||
* {@link AuthenticationFailureHandler} to allow the failure information to be conveyed to the client.
|
||||
* The default implementation is {@link SimpleUrlAuthenticationFailureHandler}, which sends a 401 error code to the
|
||||
* client. It may also be configured with a failure URL as an alternative. Again you can inject whatever
|
||||
* behaviour you require here.
|
||||
*
|
||||
* <h4>Event Publication</h4>
|
||||
*
|
||||
* If authentication is successful, an
|
||||
* {@link org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
|
||||
* InteractiveAuthenticationSuccessEvent} will be published via the application context. No events will be published if
|
||||
* authentication was unsuccessful, because this would generally be recorded via an
|
||||
* <tt>AuthenticationManager</tt>-specific application event.
|
||||
* <p>
|
||||
* The filter has an optional attribute <tt>invalidateSessionOnSuccessfulAuthentication</tt> that will invalidate
|
||||
* the current session on successful authentication. This is to protect against session fixation attacks (see
|
||||
* <a href="http://en.wikipedia.org/wiki/Session_fixation">this Wikipedia article</a> for more information).
|
||||
* The behaviour is turned off by default. Additionally there is a property <tt>migrateInvalidatedSessionAttributes</tt>
|
||||
* which tells if on session invalidation we are to migrate all session attributes from the old session to a newly
|
||||
* created one. This is turned on by default, but not used unless <tt>invalidateSessionOnSuccessfulAuthentication</tt>
|
||||
* is true. If you are using this feature in combination with concurrent session control, you should set the
|
||||
* <tt>sessionRegistry</tt> property to make sure that the session information is updated consistently.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @deprecated Use AbstractAuthenticationProcessingFilter instead.
|
||||
*/
|
||||
public abstract class AbstractProcessingFilter extends SpringSecurityFilter implements InitializingBean,
|
||||
ApplicationEventPublisherAware, MessageSourceAware {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@Deprecated
|
||||
public abstract class AbstractProcessingFilter extends AbstractAuthenticationProcessingFilter {
|
||||
|
||||
public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = "SPRING_SECURITY_LAST_EXCEPTION";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected ApplicationEventPublisher eventPublisher;
|
||||
protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||
private AuthenticationManager authenticationManager;
|
||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
|
||||
/*
|
||||
* Delay use of NullRememberMeServices until initialization so that namespace has a chance to inject
|
||||
* the RememberMeServices implementation into custom implementations.
|
||||
*/
|
||||
private RememberMeServices rememberMeServices = null;
|
||||
|
||||
/**
|
||||
* The URL destination that this filter intercepts and processes (usually
|
||||
* something like <code>/j_spring_security_check</code>)
|
||||
*/
|
||||
private String filterProcessesUrl;
|
||||
|
||||
private boolean continueChainBeforeSuccessfulAuthentication = false;
|
||||
|
||||
/**
|
||||
* Tells if we on successful authentication should invalidate the
|
||||
* current session. This is a common guard against session fixation attacks.
|
||||
* Defaults to <code>false</code>.
|
||||
*/
|
||||
private boolean invalidateSessionOnSuccessfulAuthentication = false;
|
||||
|
||||
/**
|
||||
* If {@link #invalidateSessionOnSuccessfulAuthentication} is true, this
|
||||
* flag indicates that the session attributes of the session to be invalidated
|
||||
* are to be migrated to the new session. Defaults to <code>true</code> since
|
||||
* nothing will happen unless {@link #invalidateSessionOnSuccessfulAuthentication}
|
||||
* is true.
|
||||
*/
|
||||
private boolean migrateInvalidatedSessionAttributes = true;
|
||||
|
||||
private boolean allowSessionCreation = true;
|
||||
|
||||
private SessionRegistry sessionRegistry;
|
||||
|
||||
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||
private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>.
|
||||
*/
|
||||
protected AbstractProcessingFilter(String defaultFilterProcessesUrl) {
|
||||
this.filterProcessesUrl = defaultFilterProcessesUrl;
|
||||
}
|
||||
|
||||
//~ 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.notNull(authenticationManager, "authenticationManager must be specified");
|
||||
|
||||
if (rememberMeServices == null) {
|
||||
rememberMeServices = new NullRememberMeServices();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* <ol>
|
||||
* <li>An <tt>Authentication</tt> object is returned.
|
||||
* The {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* successfulAuthentication} method will be invoked</li>
|
||||
* <li>An <tt>AuthenticationException</tt> occurs during authentication.
|
||||
* The {@link #unSuccessfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* unSuccessfulAuthentication} method will be invoked</li>
|
||||
* <li>Null is returned, indicating that the authentication process is incomplete.
|
||||
* The method will then return immediately, assuming that the subclass has done any necessary work (such as
|
||||
* redirects) to continue the authentication process. The assumption is that a later request will be received
|
||||
* by this method where the returned <tt>Authentication</tt> object is not null.
|
||||
* </ol>
|
||||
*/
|
||||
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
if (!requiresAuthentication(request, response)) {
|
||||
chain.doFilter(request, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Request is to process authentication");
|
||||
}
|
||||
|
||||
Authentication authResult;
|
||||
|
||||
try {
|
||||
authResult = attemptAuthentication(request, response);
|
||||
if (authResult == null) {
|
||||
// return immediately as subclass has indicated that it hasn't completed authentication
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (AuthenticationException failed) {
|
||||
// Authentication failed
|
||||
unsuccessfulAuthentication(request, response, failed);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Authentication success
|
||||
if (continueChainBeforeSuccessfulAuthentication) {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
successfulAuthentication(request, response, authResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this filter should attempt to process a login request for the current invocation.
|
||||
* <p>
|
||||
* It strips any parameters from the "path" section of the request URL (such
|
||||
* as the jsessionid parameter in
|
||||
* <em>http://host/myapp/index.html;jsessionid=blah</em>) before matching
|
||||
* against the <code>filterProcessesUrl</code> property.
|
||||
* <p>
|
||||
* Subclasses may override for special requirements, such as Tapestry integration.
|
||||
*
|
||||
* @return <code>true</code> if the filter should attempt authentication, <code>false</code> otherwise.
|
||||
*/
|
||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||
String uri = request.getRequestURI();
|
||||
int pathParamIndex = uri.indexOf(';');
|
||||
|
||||
if (pathParamIndex > 0) {
|
||||
// strip everything after the first semi-colon
|
||||
uri = uri.substring(0, pathParamIndex);
|
||||
}
|
||||
|
||||
if ("".equals(request.getContextPath())) {
|
||||
return uri.endsWith(filterProcessesUrl);
|
||||
}
|
||||
|
||||
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs actual authentication.
|
||||
* <p>
|
||||
* The implementation should do one of the following:
|
||||
* <ol>
|
||||
* <li>Return a populated authentication token for the authenticated user, indicating successful authentication</li>
|
||||
* <li>Return null, indicating that the authentication process is still in progress. Before returning, the
|
||||
* implementation should perform any additional work required to complete the process.</li>
|
||||
* <li>Throw an <tt>AuthenticationException</tt> if the authentication process fails</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param request from which to extract parameters and perform the authentication
|
||||
* @param response the response, which may be needed if the implementation has to do a redirect as part of a
|
||||
* multi-stage authentication process (such as OpenID).
|
||||
*
|
||||
* @return the authenticated user token, or null if authentication is incomplete.
|
||||
*
|
||||
* @throws AuthenticationException if authentication fails.
|
||||
*/
|
||||
public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException, IOException, ServletException;
|
||||
|
||||
/**
|
||||
* Default behaviour for successful authentication.
|
||||
* <ol>
|
||||
* <li>Sets the successful <tt>Authentication</tt> object on the {@link SecurityContextHolder}</li>
|
||||
* <li>Performs any configured session migration behaviour</li>
|
||||
* <li>Informs the configured <tt>RememberMeServices</tt> of the successful login</li>
|
||||
* <li>Fires an {@link InteractiveAuthenticationSuccessEvent} via the configured
|
||||
* <tt>ApplicationEventPublisher</tt></li>
|
||||
* <li>Delegates additional behaviour to the {@link AuthenticationSuccessHandler}.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param authResult the object returned from the <tt>attemptAuthentication</tt> method.
|
||||
*/
|
||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authResult) throws IOException, ServletException {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
|
||||
}
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(authResult);
|
||||
|
||||
if (invalidateSessionOnSuccessfulAuthentication) {
|
||||
SessionUtils.startNewSessionIfRequired(request, migrateInvalidatedSessionAttributes, sessionRegistry);
|
||||
}
|
||||
|
||||
rememberMeServices.loginSuccess(request, response, authResult);
|
||||
|
||||
// Fire event
|
||||
if (this.eventPublisher != null) {
|
||||
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
|
||||
}
|
||||
|
||||
successHandler.onAuthenticationSuccess(request, response, authResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default behaviour for unsuccessful authentication.
|
||||
* <ol>
|
||||
* <li>Clears the {@link SecurityContextHolder}</li>
|
||||
* <li>Stores the exception in the session (if it exists or <tt>allowSesssionCreation</tt> is set to <tt>true</tt>)</li>
|
||||
* <li>Informs the configured <tt>RememberMeServices</tt> of the failed login</li>
|
||||
* <li>Delegates additional behaviour to the {@link AuthenticationFailureHandler}.</li>
|
||||
* </ol>
|
||||
*/
|
||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException failed) throws IOException, ServletException {
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request failed: " + failed.toString());
|
||||
logger.debug("Updated SecurityContextHolder to contain null Authentication");
|
||||
logger.debug("Delegating to authentication failure handler" + failureHandler);
|
||||
}
|
||||
|
||||
try {
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null || allowSessionCreation) {
|
||||
request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||
}
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
|
||||
rememberMeServices.loginFail(request, response);
|
||||
|
||||
failureHandler.onAuthenticationFailure(request, response, failed);
|
||||
}
|
||||
|
||||
protected AuthenticationManager getAuthenticationManager() {
|
||||
return authenticationManager;
|
||||
}
|
||||
|
||||
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
|
||||
public String getFilterProcessesUrl() {
|
||||
return filterProcessesUrl;
|
||||
}
|
||||
|
||||
public void setFilterProcessesUrl(String filterProcessesUrl) {
|
||||
this.filterProcessesUrl = filterProcessesUrl;
|
||||
}
|
||||
|
||||
public RememberMeServices getRememberMeServices() {
|
||||
return rememberMeServices;
|
||||
}
|
||||
|
||||
public void setRememberMeServices(RememberMeServices rememberMeServices) {
|
||||
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 <code>false</code>.
|
||||
*/
|
||||
public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
|
||||
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
|
||||
}
|
||||
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
|
||||
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
|
||||
this.authenticationDetailsSource = authenticationDetailsSource;
|
||||
}
|
||||
|
||||
public void setMessageSource(MessageSource messageSource) {
|
||||
this.messages = new MessageSourceAccessor(messageSource);
|
||||
}
|
||||
|
||||
public void setInvalidateSessionOnSuccessfulAuthentication(boolean invalidateSessionOnSuccessfulAuthentication) {
|
||||
this.invalidateSessionOnSuccessfulAuthentication = invalidateSessionOnSuccessfulAuthentication;
|
||||
}
|
||||
|
||||
public void setMigrateInvalidatedSessionAttributes(boolean migrateInvalidatedSessionAttributes) {
|
||||
this.migrateInvalidatedSessionAttributes = migrateInvalidatedSessionAttributes;
|
||||
}
|
||||
|
||||
public AuthenticationDetailsSource getAuthenticationDetailsSource() {
|
||||
// Required due to SEC-310
|
||||
return authenticationDetailsSource;
|
||||
}
|
||||
|
||||
protected boolean getAllowSessionCreation() {
|
||||
return allowSessionCreation;
|
||||
}
|
||||
|
||||
public void setAllowSessionCreation(boolean allowSessionCreation) {
|
||||
this.allowSessionCreation = allowSessionCreation;
|
||||
}
|
||||
|
||||
/**
|
||||
* The session registry needs to be set if session fixation attack protection is in use (and concurrent
|
||||
* session control is enabled).
|
||||
*/
|
||||
public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the strategy used to handle a successful authentication.
|
||||
* By default a {@link SavedRequestAwareAuthenticationSuccessHandler} is used.
|
||||
*/
|
||||
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
|
||||
Assert.notNull(successHandler, "successHandler cannot be null");
|
||||
this.successHandler = successHandler;
|
||||
}
|
||||
|
||||
public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
|
||||
Assert.notNull(failureHandler, "failureHandler cannot be null");
|
||||
this.failureHandler = failureHandler;
|
||||
super(defaultFilterProcessesUrl);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-172
@@ -1,182 +1,15 @@
|
||||
/* 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.web.authentication;
|
||||
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
import org.springframework.security.web.FilterChainOrder;
|
||||
import org.springframework.security.web.util.TextEscapeUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* Processes an authentication form.
|
||||
* Renamed class, retained for backwards compatibility.
|
||||
* <p>
|
||||
* Login forms must present two parameters to this filter: a username and
|
||||
* password. The default parameter names to use are contained in the
|
||||
* static fields {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}.
|
||||
* The parameter names can also be changed by setting the <tt>usernameParameter</tt> and <tt>passwordParameter</tt>
|
||||
* properties.
|
||||
* <p>
|
||||
* This filter by default responds to the URL <tt>/j_spring_security_check</tt>.
|
||||
* See {@link UsernamePasswordAuthenticationProcessingFilter}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Colin Sampaleanu
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @deprecated Use UsernamePasswordAuthenticationProcessingFilter instead.
|
||||
*/
|
||||
public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
|
||||
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
|
||||
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
|
||||
public class AuthenticationProcessingFilter extends UsernamePasswordAuthenticationProcessingFilter {
|
||||
|
||||
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
|
||||
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
|
||||
private boolean postOnly = true;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public AuthenticationProcessingFilter() {
|
||||
super("/j_spring_security_check");
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
if (postOnly && !request.getMethod().equals("POST")) {
|
||||
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
|
||||
}
|
||||
|
||||
String username = obtainUsername(request);
|
||||
String password = obtainPassword(request);
|
||||
|
||||
if (username == null) {
|
||||
username = "";
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
username = username.trim();
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
|
||||
|
||||
// Place the last username attempted into HttpSession for views
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null || getAllowSessionCreation()) {
|
||||
request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
|
||||
}
|
||||
|
||||
// Allow subclasses to set the "details" property
|
||||
setDetails(request, authRequest);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables subclasses to override the composition of the password, such as by including additional values
|
||||
* and a separator.<p>This might be used for example if a postcode/zipcode was required in addition to the
|
||||
* password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
|
||||
* <code>AuthenticationDao</code> will need to generate the expected password in a corresponding manner.</p>
|
||||
*
|
||||
* @param request so that request attributes can be retrieved
|
||||
*
|
||||
* @return the password that will be presented in the <code>Authentication</code> request token to the
|
||||
* <code>AuthenticationManager</code>
|
||||
*/
|
||||
protected String obtainPassword(HttpServletRequest request) {
|
||||
return request.getParameter(passwordParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables subclasses to override the composition of the username, such as by including additional values
|
||||
* and a separator.
|
||||
*
|
||||
* @param request so that request attributes can be retrieved
|
||||
*
|
||||
* @return the username that will be presented in the <code>Authentication</code> request token to the
|
||||
* <code>AuthenticationManager</code>
|
||||
*/
|
||||
protected String obtainUsername(HttpServletRequest request) {
|
||||
return request.getParameter(usernameParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided so that subclasses may configure what is put into the authentication request's details
|
||||
* property.
|
||||
*
|
||||
* @param request that an authentication request is being created for
|
||||
* @param authRequest the authentication request object that should have its details set
|
||||
*/
|
||||
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameter name which will be used to obtain the username from the login request.
|
||||
*
|
||||
* @param usernameParameter the parameter name. Defaults to "j_username".
|
||||
*/
|
||||
public void setUsernameParameter(String usernameParameter) {
|
||||
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
|
||||
this.usernameParameter = usernameParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameter name which will be used to obtain the password from the login request..
|
||||
*
|
||||
* @param passwordParameter the parameter name. Defaults to "j_password".
|
||||
*/
|
||||
public void setPasswordParameter(String passwordParameter) {
|
||||
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
|
||||
this.passwordParameter = passwordParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether only HTTP POST requests will be allowed by this filter.
|
||||
* If set to true, and an authentication request is received which is not a POST request, an exception will
|
||||
* be raised immediately and authentication will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method
|
||||
* will be called as if handling a failed authentication.
|
||||
* <p>
|
||||
* Defaults to <tt>true</tt> but may be overridden by subclasses.
|
||||
*/
|
||||
public void setPostOnly(boolean postOnly) {
|
||||
this.postOnly = postOnly;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return FilterChainOrder.AUTHENTICATION_PROCESSING_FILTER;
|
||||
}
|
||||
|
||||
public final String getUsernameParameter() {
|
||||
return usernameParameter;
|
||||
}
|
||||
|
||||
public final String getPasswordParameter() {
|
||||
return passwordParameter;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-249
@@ -1,258 +1,14 @@
|
||||
/* 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.web.authentication;
|
||||
|
||||
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.PortMapper;
|
||||
import org.springframework.security.web.PortMapperImpl;
|
||||
import org.springframework.security.web.PortResolver;
|
||||
import org.springframework.security.web.PortResolverImpl;
|
||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||
import org.springframework.security.web.util.RedirectUrlBuilder;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
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;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Used by the {@link ExceptionTranslationFilter} to commence a form login
|
||||
* authentication via the {@link AuthenticationProcessingFilter}. This object
|
||||
* holds the location of the login form, relative to the web app context path,
|
||||
* and is used to commence a redirect to that form.
|
||||
* Renamed class, retained for backwards compatibility.
|
||||
* <p>
|
||||
* By setting the <em>forceHttps</em> property to true, you may configure the
|
||||
* class to force the protocol used for the login form to be <code>HTTPS</code>,
|
||||
* even if the original intercepted request for a resource used the
|
||||
* <code>HTTP</code> protocol. When this happens, after a successful login
|
||||
* (via HTTPS), the original resource will still be accessed as HTTP, via the
|
||||
* original request URL. For the forced HTTPS feature to work, the {@link
|
||||
* PortMapper} is consulted to determine the HTTP:HTTPS pairs.
|
||||
* See {@link LoginUrlAuthenticationEntryPoint}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author colin sampaleanu
|
||||
* @author Omri Spector
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @deprecated Use LoginUrlAuthenticationEntryPoint instead.
|
||||
*/
|
||||
public class AuthenticationProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint{
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private PortMapper portMapper = new PortMapperImpl();
|
||||
|
||||
private PortResolver portResolver = new PortResolverImpl();
|
||||
|
||||
private String loginFormUrl;
|
||||
|
||||
private boolean forceHttps = false;
|
||||
|
||||
private boolean useForward = false;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to modify the login form URL that should be applicable for a given request.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param exception the exception
|
||||
* @return the URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()})
|
||||
*/
|
||||
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
|
||||
return getLoginFormUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the redirect (or forward) to the login form URL.
|
||||
*/
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
|
||||
throws IOException, ServletException {
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
|
||||
String redirectUrl = null;
|
||||
|
||||
if (useForward) {
|
||||
|
||||
if (forceHttps && "http".equals(request.getScheme())) {
|
||||
redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest);
|
||||
}
|
||||
|
||||
if (redirectUrl == null) {
|
||||
String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Server side forward to: " + loginForm);
|
||||
}
|
||||
|
||||
RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginForm);
|
||||
|
||||
dispatcher.forward(request, response);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// redirect to login page. Use https if forceHttps true
|
||||
|
||||
redirectUrl = buildRedirectUrlToLoginPage(httpRequest, httpResponse, authException);
|
||||
|
||||
}
|
||||
|
||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
|
||||
}
|
||||
|
||||
protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) {
|
||||
|
||||
String loginForm = determineUrlToUseForThisRequest(request, response, authException);
|
||||
int serverPort = portResolver.getServerPort(request);
|
||||
String scheme = request.getScheme();
|
||||
|
||||
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
|
||||
|
||||
urlBuilder.setScheme(scheme);
|
||||
urlBuilder.setServerName(request.getServerName());
|
||||
urlBuilder.setPort(serverPort);
|
||||
urlBuilder.setContextPath(request.getContextPath());
|
||||
urlBuilder.setPathInfo(loginForm);
|
||||
|
||||
if (forceHttps && "http".equals(scheme)) {
|
||||
Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
|
||||
|
||||
if (httpsPort != null) {
|
||||
// Overwrite scheme and port in the redirect URL
|
||||
urlBuilder.setScheme("https");
|
||||
urlBuilder.setPort(httpsPort.intValue());
|
||||
} else {
|
||||
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
|
||||
}
|
||||
}
|
||||
|
||||
return urlBuilder.getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a URL to redirect the supplied request to HTTPS.
|
||||
*/
|
||||
protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
|
||||
throws IOException, ServletException {
|
||||
|
||||
int serverPort = portResolver.getServerPort(request);
|
||||
Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
|
||||
|
||||
if (httpsPort != null) {
|
||||
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
|
||||
urlBuilder.setScheme("https");
|
||||
urlBuilder.setServerName(request.getServerName());
|
||||
urlBuilder.setPort(httpsPort.intValue());
|
||||
urlBuilder.setContextPath(request.getContextPath());
|
||||
urlBuilder.setServletPath(request.getServletPath());
|
||||
urlBuilder.setPathInfo(request.getPathInfo());
|
||||
urlBuilder.setQuery(request.getQueryString());
|
||||
|
||||
return urlBuilder.getUrl();
|
||||
}
|
||||
|
||||
// Fall through to server-side forward with warning message
|
||||
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to force login form access to be via https. If this value is true (the default is false),
|
||||
* and the incoming request for the protected resource which triggered the interceptor was not already
|
||||
* <code>https</code>, then the client will first be redirected to an https URL, even if <tt>serverSideRedirect</tt>
|
||||
* is set to <tt>true</tt>.
|
||||
*/
|
||||
public void setForceHttps(boolean forceHttps) {
|
||||
this.forceHttps = forceHttps;
|
||||
}
|
||||
|
||||
protected boolean isForceHttps() {
|
||||
return forceHttps;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL where the <code>AuthenticationProcessingFilter</code> login
|
||||
* page can be found. Should be relative to the web-app context path, and
|
||||
* include a leading <code>/</code>
|
||||
*/
|
||||
public void setLoginFormUrl(String loginFormUrl) {
|
||||
this.loginFormUrl = loginFormUrl;
|
||||
}
|
||||
|
||||
public String getLoginFormUrl() {
|
||||
return loginFormUrl;
|
||||
}
|
||||
|
||||
public void setPortMapper(PortMapper portMapper) {
|
||||
this.portMapper = portMapper;
|
||||
}
|
||||
|
||||
protected PortMapper getPortMapper() {
|
||||
return portMapper;
|
||||
}
|
||||
|
||||
public void setPortResolver(PortResolver portResolver) {
|
||||
this.portResolver = portResolver;
|
||||
}
|
||||
|
||||
protected PortResolver getPortResolver() {
|
||||
return portResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if we are to do a forward to the <code>loginFormUrl</code> using the <tt>RequestDispatcher</tt>,
|
||||
* instead of a 302 redirect.
|
||||
*
|
||||
* @param useForward
|
||||
*/
|
||||
public void setUseForward(boolean useForward) {
|
||||
this.useForward = useForward;
|
||||
}
|
||||
|
||||
protected boolean isUseForward() {
|
||||
return useForward;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.springframework.security.core.Authentication;
|
||||
* Implementations can do whatever they want but typical behaviour would be to control the navigation to the
|
||||
* subsequent destination (using a redirect or a forward). For example, after a user has logged in by submitting a
|
||||
* login form, the application needs to decide where they should be redirected to afterwards
|
||||
* (see {@link AbstractProcessingFilter} and subclasses). Other logic may also be included if required.
|
||||
* (see {@link AbstractAuthenticationProcessingFilter} and subclasses). Other logic may also be included if required.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
package org.springframework.security.web.authentication;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* In the pre-authenticated authentication case (unlike CAS, for example) the
|
||||
* user will already have been identified through some external mechanism and a
|
||||
* secure context established by the time the security-enforcement filter is
|
||||
* invoked.
|
||||
* <p>
|
||||
* Therefore this class isn't actually responsible for the commencement of
|
||||
* authentication, as it is in the case of other providers. It will be called if
|
||||
* the user is rejected by the AbstractPreAuthenticatedProcessingFilter,
|
||||
* resulting in a null authentication.
|
||||
* <p>
|
||||
* The <code>commence</code> method will always return an
|
||||
* <code>HttpServletResponse.SC_FORBIDDEN</code> (403 error).
|
||||
*
|
||||
* @see org.springframework.security.web.access.ExceptionTranslationFilter
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @author Ruud Senden
|
||||
* @since 2.0
|
||||
*/
|
||||
public class Http403ForbiddenEntryPoint implements AuthenticationEntryPoint, Ordered {
|
||||
private static final Log logger = LogFactory.getLog(Http403ForbiddenEntryPoint.class);
|
||||
|
||||
private int order = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Always returns a 403 error code to the client.
|
||||
*/
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
|
||||
ServletException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Pre-authenticated entry point called. Rejecting access");
|
||||
}
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int i) {
|
||||
order = i;
|
||||
}
|
||||
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
/* 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.web.authentication;
|
||||
|
||||
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.PortMapper;
|
||||
import org.springframework.security.web.PortMapperImpl;
|
||||
import org.springframework.security.web.PortResolver;
|
||||
import org.springframework.security.web.PortResolverImpl;
|
||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||
import org.springframework.security.web.util.RedirectUrlBuilder;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
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;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Used by the {@link ExceptionTranslationFilter} to commence a form login
|
||||
* authentication via the {@link UsernamePasswordAuthenticationProcessingFilter}. This object
|
||||
* holds the location of the login form, relative to the web app context path,
|
||||
* and is used to commence a redirect to that form.
|
||||
* <p>
|
||||
* By setting the <em>forceHttps</em> property to true, you may configure the
|
||||
* class to force the protocol used for the login form to be <code>HTTPS</code>,
|
||||
* even if the original intercepted request for a resource used the
|
||||
* <code>HTTP</code> protocol. When this happens, after a successful login
|
||||
* (via HTTPS), the original resource will still be accessed as HTTP, via the
|
||||
* original request URL. For the forced HTTPS feature to work, the {@link
|
||||
* PortMapper} is consulted to determine the HTTP:HTTPS pairs.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author colin sampaleanu
|
||||
* @author Omri Spector
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(LoginUrlAuthenticationEntryPoint.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private PortMapper portMapper = new PortMapperImpl();
|
||||
|
||||
private PortResolver portResolver = new PortResolverImpl();
|
||||
|
||||
private String loginFormUrl;
|
||||
|
||||
private boolean forceHttps = false;
|
||||
|
||||
private boolean useForward = false;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to modify the login form URL that should be applicable for a given request.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param exception the exception
|
||||
* @return the URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()})
|
||||
*/
|
||||
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
|
||||
return getLoginFormUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the redirect (or forward) to the login form URL.
|
||||
*/
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
|
||||
throws IOException, ServletException {
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
|
||||
String redirectUrl = null;
|
||||
|
||||
if (useForward) {
|
||||
|
||||
if (forceHttps && "http".equals(request.getScheme())) {
|
||||
redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest);
|
||||
}
|
||||
|
||||
if (redirectUrl == null) {
|
||||
String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Server side forward to: " + loginForm);
|
||||
}
|
||||
|
||||
RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginForm);
|
||||
|
||||
dispatcher.forward(request, response);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// redirect to login page. Use https if forceHttps true
|
||||
|
||||
redirectUrl = buildRedirectUrlToLoginPage(httpRequest, httpResponse, authException);
|
||||
|
||||
}
|
||||
|
||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
|
||||
}
|
||||
|
||||
protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) {
|
||||
|
||||
String loginForm = determineUrlToUseForThisRequest(request, response, authException);
|
||||
int serverPort = portResolver.getServerPort(request);
|
||||
String scheme = request.getScheme();
|
||||
|
||||
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
|
||||
|
||||
urlBuilder.setScheme(scheme);
|
||||
urlBuilder.setServerName(request.getServerName());
|
||||
urlBuilder.setPort(serverPort);
|
||||
urlBuilder.setContextPath(request.getContextPath());
|
||||
urlBuilder.setPathInfo(loginForm);
|
||||
|
||||
if (forceHttps && "http".equals(scheme)) {
|
||||
Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
|
||||
|
||||
if (httpsPort != null) {
|
||||
// Overwrite scheme and port in the redirect URL
|
||||
urlBuilder.setScheme("https");
|
||||
urlBuilder.setPort(httpsPort.intValue());
|
||||
} else {
|
||||
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
|
||||
}
|
||||
}
|
||||
|
||||
return urlBuilder.getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a URL to redirect the supplied request to HTTPS.
|
||||
*/
|
||||
protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
|
||||
throws IOException, ServletException {
|
||||
|
||||
int serverPort = portResolver.getServerPort(request);
|
||||
Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
|
||||
|
||||
if (httpsPort != null) {
|
||||
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
|
||||
urlBuilder.setScheme("https");
|
||||
urlBuilder.setServerName(request.getServerName());
|
||||
urlBuilder.setPort(httpsPort.intValue());
|
||||
urlBuilder.setContextPath(request.getContextPath());
|
||||
urlBuilder.setServletPath(request.getServletPath());
|
||||
urlBuilder.setPathInfo(request.getPathInfo());
|
||||
urlBuilder.setQuery(request.getQueryString());
|
||||
|
||||
return urlBuilder.getUrl();
|
||||
}
|
||||
|
||||
// Fall through to server-side forward with warning message
|
||||
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to force login form access to be via https. If this value is true (the default is false),
|
||||
* and the incoming request for the protected resource which triggered the interceptor was not already
|
||||
* <code>https</code>, then the client will first be redirected to an https URL, even if <tt>serverSideRedirect</tt>
|
||||
* is set to <tt>true</tt>.
|
||||
*/
|
||||
public void setForceHttps(boolean forceHttps) {
|
||||
this.forceHttps = forceHttps;
|
||||
}
|
||||
|
||||
protected boolean isForceHttps() {
|
||||
return forceHttps;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL where the <code>UsernamePasswordAuthenticationProcessingFilter</code> login
|
||||
* page can be found. Should be relative to the web-app context path, and
|
||||
* include a leading <code>/</code>
|
||||
*/
|
||||
public void setLoginFormUrl(String loginFormUrl) {
|
||||
this.loginFormUrl = loginFormUrl;
|
||||
}
|
||||
|
||||
public String getLoginFormUrl() {
|
||||
return loginFormUrl;
|
||||
}
|
||||
|
||||
public void setPortMapper(PortMapper portMapper) {
|
||||
this.portMapper = portMapper;
|
||||
}
|
||||
|
||||
protected PortMapper getPortMapper() {
|
||||
return portMapper;
|
||||
}
|
||||
|
||||
public void setPortResolver(PortResolver portResolver) {
|
||||
this.portResolver = portResolver;
|
||||
}
|
||||
|
||||
protected PortResolver getPortResolver() {
|
||||
return portResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if we are to do a forward to the <code>loginFormUrl</code> using the <tt>RequestDispatcher</tt>,
|
||||
* instead of a 302 redirect.
|
||||
*
|
||||
* @param useForward
|
||||
*/
|
||||
public void setUseForward(boolean useForward) {
|
||||
this.useForward = useForward;
|
||||
}
|
||||
|
||||
protected boolean isUseForward() {
|
||||
return useForward;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ import org.springframework.security.core.Authentication;
|
||||
* Implement by a class that is capable of providing a remember-me service.
|
||||
*
|
||||
* <p>
|
||||
* Spring Security filters (namely {@link org.springframework.security.web.authentication.AbstractProcessingFilter} and
|
||||
* Spring Security filters (namely {@link org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and
|
||||
* {@link RememberMeProcessingFilter} will call the methods provided by an implementation of this interface.
|
||||
* <p>
|
||||
* Implementations may implement any type of remember-me capability they wish.
|
||||
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/* 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.web.authentication;
|
||||
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
import org.springframework.security.web.FilterChainOrder;
|
||||
import org.springframework.security.web.util.TextEscapeUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* Processes an authentication form. Called <tt>AuthenticationProcessingFilter<tt> in previous versions
|
||||
* of the framework.
|
||||
* <p>
|
||||
* Login forms must present two parameters to this filter: a username and
|
||||
* password. The default parameter names to use are contained in the
|
||||
* static fields {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}.
|
||||
* The parameter names can also be changed by setting the <tt>usernameParameter</tt> and <tt>passwordParameter</tt>
|
||||
* properties.
|
||||
* <p>
|
||||
* This filter by default responds to the URL <tt>/j_spring_security_check</tt>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Colin Sampaleanu
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class UsernamePasswordAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
|
||||
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
|
||||
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
|
||||
|
||||
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
|
||||
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
|
||||
private boolean postOnly = true;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public UsernamePasswordAuthenticationProcessingFilter() {
|
||||
super("/j_spring_security_check");
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
if (postOnly && !request.getMethod().equals("POST")) {
|
||||
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
|
||||
}
|
||||
|
||||
String username = obtainUsername(request);
|
||||
String password = obtainPassword(request);
|
||||
|
||||
if (username == null) {
|
||||
username = "";
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
username = username.trim();
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
|
||||
|
||||
// Place the last username attempted into HttpSession for views
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null || getAllowSessionCreation()) {
|
||||
request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
|
||||
}
|
||||
|
||||
// Allow subclasses to set the "details" property
|
||||
setDetails(request, authRequest);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables subclasses to override the composition of the password, such as by including additional values
|
||||
* and a separator.<p>This might be used for example if a postcode/zipcode was required in addition to the
|
||||
* password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
|
||||
* <code>AuthenticationDao</code> will need to generate the expected password in a corresponding manner.</p>
|
||||
*
|
||||
* @param request so that request attributes can be retrieved
|
||||
*
|
||||
* @return the password that will be presented in the <code>Authentication</code> request token to the
|
||||
* <code>AuthenticationManager</code>
|
||||
*/
|
||||
protected String obtainPassword(HttpServletRequest request) {
|
||||
return request.getParameter(passwordParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables subclasses to override the composition of the username, such as by including additional values
|
||||
* and a separator.
|
||||
*
|
||||
* @param request so that request attributes can be retrieved
|
||||
*
|
||||
* @return the username that will be presented in the <code>Authentication</code> request token to the
|
||||
* <code>AuthenticationManager</code>
|
||||
*/
|
||||
protected String obtainUsername(HttpServletRequest request) {
|
||||
return request.getParameter(usernameParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided so that subclasses may configure what is put into the authentication request's details
|
||||
* property.
|
||||
*
|
||||
* @param request that an authentication request is being created for
|
||||
* @param authRequest the authentication request object that should have its details set
|
||||
*/
|
||||
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameter name which will be used to obtain the username from the login request.
|
||||
*
|
||||
* @param usernameParameter the parameter name. Defaults to "j_username".
|
||||
*/
|
||||
public void setUsernameParameter(String usernameParameter) {
|
||||
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
|
||||
this.usernameParameter = usernameParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameter name which will be used to obtain the password from the login request..
|
||||
*
|
||||
* @param passwordParameter the parameter name. Defaults to "j_password".
|
||||
*/
|
||||
public void setPasswordParameter(String passwordParameter) {
|
||||
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
|
||||
this.passwordParameter = passwordParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether only HTTP POST requests will be allowed by this filter.
|
||||
* If set to true, and an authentication request is received which is not a POST request, an exception will
|
||||
* be raised immediately and authentication will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method
|
||||
* will be called as if handling a failed authentication.
|
||||
* <p>
|
||||
* Defaults to <tt>true</tt> but may be overridden by subclasses.
|
||||
*/
|
||||
public void setPostOnly(boolean postOnly) {
|
||||
this.postOnly = postOnly;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return FilterChainOrder.AUTHENTICATION_PROCESSING_FILTER;
|
||||
}
|
||||
|
||||
public final String getUsernameParameter() {
|
||||
return usernameParameter;
|
||||
}
|
||||
|
||||
public final String getPasswordParameter() {
|
||||
return passwordParameter;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -8,7 +8,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.web.SpringSecurityFilter;
|
||||
import org.springframework.security.web.authentication.AbstractProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
@@ -128,7 +128,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends SpringSec
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Cleared security context due to exception", failed);
|
||||
}
|
||||
request.getSession().setAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||
request.getSession().setAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Executable → Regular
+16
-65
@@ -1,65 +1,16 @@
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* In the pre-authenticated authentication case (unlike CAS, for example) the
|
||||
* user will already have been identified through some external mechanism and a
|
||||
* secure context established by the time the security-enforcement filter is
|
||||
* invoked.
|
||||
* <p>
|
||||
* Therefore this class isn't actually responsible for the commencement of
|
||||
* authentication, as it is in the case of other providers. It will be called if
|
||||
* the user is rejected by the AbstractPreAuthenticatedProcessingFilter,
|
||||
* resulting in a null authentication.
|
||||
* <p>
|
||||
* The <code>commence</code> method will always return an
|
||||
* <code>HttpServletResponse.SC_FORBIDDEN</code> (403 error).
|
||||
* <p>
|
||||
* This code is based on
|
||||
* {@link org.springframework.security.ui.x509.X509ProcessingFilterEntryPoint}.
|
||||
*
|
||||
* @see org.springframework.security.web.access.ExceptionTranslationFilter
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @author Ruud Senden
|
||||
* @since 2.0
|
||||
*/
|
||||
public class PreAuthenticatedProcessingFilterEntryPoint implements AuthenticationEntryPoint, Ordered {
|
||||
private static final Log logger = LogFactory.getLog(PreAuthenticatedProcessingFilterEntryPoint.class);
|
||||
|
||||
private int order = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Always returns a 403 error code to the client.
|
||||
*/
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
|
||||
ServletException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Pre-authenticated entry point called. Rejecting access");
|
||||
}
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int i) {
|
||||
order = i;
|
||||
}
|
||||
|
||||
}
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
|
||||
|
||||
/**
|
||||
* Renamed class, retained for backwards compatibility.
|
||||
* <p>
|
||||
* See {@link Http403ForbiddenEntryPoint}.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @deprecated Use Http403ForbiddenEntryPoint instead.
|
||||
*/
|
||||
public class PreAuthenticatedProcessingFilterEntryPoint extends Http403ForbiddenEntryPoint {
|
||||
|
||||
}
|
||||
|
||||
+9
-9
@@ -12,8 +12,8 @@ import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.FilterChainOrder;
|
||||
import org.springframework.security.web.SpringSecurityFilter;
|
||||
import org.springframework.security.web.authentication.AbstractProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
|
||||
|
||||
/**
|
||||
@@ -39,19 +39,19 @@ public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
|
||||
private String openIDusernameParameter;
|
||||
private String openIDrememberMeParameter;
|
||||
|
||||
public DefaultLoginPageGeneratingFilter(AbstractProcessingFilter filter) {
|
||||
if (filter instanceof AuthenticationProcessingFilter) {
|
||||
init((AuthenticationProcessingFilter)filter, null);
|
||||
public DefaultLoginPageGeneratingFilter(AbstractAuthenticationProcessingFilter filter) {
|
||||
if (filter instanceof UsernamePasswordAuthenticationProcessingFilter) {
|
||||
init((UsernamePasswordAuthenticationProcessingFilter)filter, null);
|
||||
} else {
|
||||
init(null, filter);
|
||||
}
|
||||
}
|
||||
|
||||
public DefaultLoginPageGeneratingFilter(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
|
||||
public DefaultLoginPageGeneratingFilter(UsernamePasswordAuthenticationProcessingFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
|
||||
init(authFilter, openIDFilter);
|
||||
}
|
||||
|
||||
private void init(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
|
||||
private void init(UsernamePasswordAuthenticationProcessingFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
|
||||
if (authFilter != null) {
|
||||
formLoginEnabled = true;
|
||||
authenticationUrl = authFilter.getFilterProcessesUrl();
|
||||
@@ -96,8 +96,8 @@ public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if(session != null) {
|
||||
lastUser = (String) session.getAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
|
||||
AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
|
||||
lastUser = (String) session.getAttribute(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
|
||||
AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
|
||||
errorMsg = ex != null ? ex.getMessage() : "none";
|
||||
if (lastUser == null) {
|
||||
lastUser = "";
|
||||
|
||||
@@ -35,7 +35,7 @@ import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Represents central information from a <code>HttpServletRequest</code>.<p>This class is used by {@link
|
||||
* org.springframework.security.web.authentication.AbstractProcessingFilter} and {@link org.springframework.security.web.wrapper.SavedRequestAwareWrapper} to
|
||||
* org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and {@link org.springframework.security.web.wrapper.SavedRequestAwareWrapper} to
|
||||
* reproduce the request after successful authentication. An instance of this class is stored at the time of an
|
||||
* authentication exception by {@link org.springframework.security.web.access.ExceptionTranslationFilter}.</p>
|
||||
* <p><em>IMPLEMENTATION NOTE</em>: It is assumed that this object is accessed only from the context of a single
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.springframework.security.web.util;
|
||||
|
||||
import org.springframework.security.web.authentication.AbstractProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -20,7 +20,7 @@ public abstract class RedirectUtils {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Encapsulates the redirect logic used in classes like {@link AbstractProcessingFilter} and {@link LogoutFilter}.
|
||||
* Encapsulates the redirect logic used in classes like {@link AbstractAuthenticationProcessingFilter} and {@link LogoutFilter}.
|
||||
*
|
||||
* @param request the incoming request
|
||||
* @param response the response to redirect
|
||||
@@ -28,7 +28,7 @@ public abstract class RedirectUtils {
|
||||
* @param useRelativeContext if true, causes any redirection URLs to be calculated minus the protocol
|
||||
* and context path.
|
||||
*
|
||||
* @see AbstractProcessingFilter#setUseRelativeContext(boolean)
|
||||
* @see AbstractAuthenticationProcessingFilter#setUseRelativeContext(boolean)
|
||||
*/
|
||||
public static final void sendRedirect(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
|
||||
+6
-6
@@ -44,7 +44,7 @@ import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.PortResolverImpl;
|
||||
import org.springframework.security.web.authentication.AbstractProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
@@ -53,7 +53,7 @@ import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link AbstractProcessingFilter}.
|
||||
* Tests {@link AbstractAuthenticationProcessingFilter}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
@@ -191,7 +191,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testGettersSetters() throws Exception {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
AbstractAuthenticationProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
filter.setAuthenticationManager(mock(AuthenticationManager.class));
|
||||
filter.setFilterProcessesUrl("/p");
|
||||
filter.afterPropertiesSet();
|
||||
@@ -254,7 +254,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
AbstractAuthenticationProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
filter.setAuthenticationFailureHandler(failureHandler);
|
||||
successHandler.setDefaultTargetUrl("/");
|
||||
filter.setAuthenticationSuccessHandler(successHandler);
|
||||
@@ -269,7 +269,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testStartupDetectsInvalidFilterProcessesUrl() throws Exception {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
AbstractAuthenticationProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
filter.setAuthenticationFailureHandler(failureHandler);
|
||||
filter.setAuthenticationManager(mock(AuthenticationManager.class));
|
||||
filter.setAuthenticationSuccessHandler(successHandler);
|
||||
@@ -520,7 +520,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockAbstractProcessingFilter extends AbstractProcessingFilter {
|
||||
private class MockAbstractProcessingFilter extends AbstractAuthenticationProcessingFilter {
|
||||
private AuthenticationException exceptionToThrow;
|
||||
private boolean grantAccess;
|
||||
|
||||
|
||||
+13
-13
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
|
||||
import org.springframework.security.MockPortResolver;
|
||||
|
||||
import org.springframework.security.web.PortMapperImpl;
|
||||
import org.springframework.security.web.authentication.AuthenticationProcessingFilterEntryPoint;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
@@ -30,7 +30,7 @@ import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link AuthenticationProcessingFilterEntryPoint}.
|
||||
* Tests {@link LoginUrlAuthenticationEntryPoint}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author colin sampaleanu
|
||||
@@ -40,7 +40,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testDetectsMissingLoginFormUrl() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
|
||||
@@ -52,7 +52,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testDetectsMissingPortMapper() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("xxx");
|
||||
ep.setPortMapper(null);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testDetectsMissingPortResolver() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("xxx");
|
||||
ep.setPortResolver(null);
|
||||
|
||||
@@ -76,7 +76,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
@@ -100,7 +100,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setForceHttps(true);
|
||||
@@ -129,7 +129,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
portMapper.setPortMappings(map);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setForceHttps(true);
|
||||
@@ -151,7 +151,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setForceHttps(true);
|
||||
@@ -170,7 +170,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testNormalOperation() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
@@ -191,7 +191,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testOperationWhenHttpsRequestsButHttpsPortUnknown() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setPortResolver(new MockPortResolver(8888, 1234));
|
||||
ep.setForceHttps(true);
|
||||
@@ -214,7 +214,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testServerSideRedirectWithoutForceHttpsForwardsToLoginPage() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setUseForward(true);
|
||||
ep.afterPropertiesSet();
|
||||
@@ -234,7 +234,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testServerSideRedirectWithForceHttpsRedirectsCurrentRequest() throws Exception {
|
||||
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
|
||||
ep.setLoginFormUrl("/hello");
|
||||
ep.setUseForward(true);
|
||||
ep.setForceHttps(true);
|
||||
|
||||
+17
-17
@@ -35,7 +35,7 @@ import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link AuthenticationProcessingFilter}.
|
||||
* Tests {@link UsernamePasswordAuthenticationProcessingFilter}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
@@ -46,10 +46,10 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
@Test
|
||||
public void testNormalOperation() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
assertEquals("/j_spring_security_check", filter.getFilterProcessesUrl());
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
filter.init(null);
|
||||
@@ -57,16 +57,16 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
assertTrue(result != null);
|
||||
assertEquals("rod", request.getSession().getAttribute(
|
||||
AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
|
||||
UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
|
||||
assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullPasswordHandledGracefully() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
|
||||
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
assertNotNull(filter.attemptAuthentication(request, new MockHttpServletResponse()));
|
||||
}
|
||||
@@ -74,16 +74,16 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
@Test
|
||||
public void testNullUsernameHandledGracefully() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
assertNotNull(filter.attemptAuthentication(request, new MockHttpServletResponse()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsingDifferentParameterNamesWorksAsExpected() throws ServletException {
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
filter.setUsernameParameter("x");
|
||||
filter.setPasswordParameter("y");
|
||||
@@ -100,10 +100,10 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
@Test
|
||||
public void testSpacesAreTrimmedCorrectlyFromUsername() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, " rod ");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, " rod ");
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
@@ -113,8 +113,8 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
@Test
|
||||
public void testFailedAuthenticationThrowsException() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
AuthenticationManager am = mock(AuthenticationManager.class);
|
||||
when(am.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException(""));
|
||||
filter.setAuthenticationManager(am);
|
||||
@@ -127,7 +127,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
|
||||
// Check username has still been set
|
||||
assertEquals("rod", request.getSession().getAttribute(
|
||||
AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
|
||||
UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +137,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
public void noSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
|
||||
filter.setAllowSessionCreation(false);
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
|
||||
|
||||
+4
-4
@@ -30,7 +30,7 @@ public class DefaultLoginPageGeneratingFilterTests {
|
||||
|
||||
@Test
|
||||
public void generatingPageWithAuthenticationProcessingFilterOnlyIsSuccessFul() throws Exception {
|
||||
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new AuthenticationProcessingFilter());
|
||||
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new UsernamePasswordAuthenticationProcessingFilter());
|
||||
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login"), new MockHttpServletResponse(), chain);
|
||||
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login;pathparam=unused"), new MockHttpServletResponse(), chain);
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class DefaultLoginPageGeneratingFilterTests {
|
||||
}
|
||||
|
||||
// Fake OpenID filter (since it's not in this module
|
||||
private static class MockProcessingFilter extends AbstractProcessingFilter {
|
||||
private static class MockProcessingFilter extends AbstractAuthenticationProcessingFilter {
|
||||
protected MockProcessingFilter() {
|
||||
super("/someurl");
|
||||
}
|
||||
@@ -65,14 +65,14 @@ public class DefaultLoginPageGeneratingFilterTests {
|
||||
/* SEC-1111 */
|
||||
@Test
|
||||
public void handlesNonIso8859CharsInErrorMessage() throws Exception {
|
||||
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new AuthenticationProcessingFilter());
|
||||
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new UsernamePasswordAuthenticationProcessingFilter());
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/spring_security_login");
|
||||
request.addParameter("login_error", "true");
|
||||
MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
String message = messages.getMessage(
|
||||
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials", Locale.KOREA);
|
||||
System.out.println("Message: " + message);
|
||||
request.getSession().setAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, new BadCredentialsException(message));
|
||||
request.getSession().setAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, new BadCredentialsException(message));
|
||||
|
||||
filter.doFilter(request, new MockHttpServletResponse(), chain);
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package org.springframework.security.web.authentication.preauth;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedProcessingFilterEntryPoint;
|
||||
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
public class PreAuthenticatedProcessingFilterEntryPointTests extends TestCase {
|
||||
|
||||
public void testGetSetOrder() {
|
||||
PreAuthenticatedProcessingFilterEntryPoint fep = new PreAuthenticatedProcessingFilterEntryPoint();
|
||||
Http403ForbiddenEntryPoint fep = new Http403ForbiddenEntryPoint();
|
||||
fep.setOrder(333);
|
||||
assertEquals(fep.getOrder(), 333);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class PreAuthenticatedProcessingFilterEntryPointTests extends TestCase {
|
||||
public void testCommence() {
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
MockHttpServletResponse resp = new MockHttpServletResponse();
|
||||
PreAuthenticatedProcessingFilterEntryPoint fep = new PreAuthenticatedProcessingFilterEntryPoint();
|
||||
Http403ForbiddenEntryPoint fep = new Http403ForbiddenEntryPoint();
|
||||
try {
|
||||
fep.commence(req,resp,new AuthenticationCredentialsNotFoundException("test"));
|
||||
assertEquals("Incorrect status",resp.getStatus(),HttpServletResponse.SC_FORBIDDEN);
|
||||
|
||||
Reference in New Issue
Block a user