mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-08 19:42:48 +00:00
Add constructors to AbstractAuthenticationProcessingFilter
Closes gh-8309
This commit is contained in:
parent
419d7264f9
commit
b7d3acc02c
@ -156,6 +156,33 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
|
|||||||
this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
|
this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance with a default filterProcessesUrl and an {@link AuthenticationManager}
|
||||||
|
*
|
||||||
|
* @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>.
|
||||||
|
* @param authenticationManager the {@link AuthenticationManager} used to authenticate an {@link Authentication} object.
|
||||||
|
* Cannot be null.
|
||||||
|
*/
|
||||||
|
protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl,
|
||||||
|
AuthenticationManager authenticationManager) {
|
||||||
|
setFilterProcessesUrl(defaultFilterProcessesUrl);
|
||||||
|
setAuthenticationManager(authenticationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance with a {@link RequestMatcher} and an {@link AuthenticationManager}
|
||||||
|
*
|
||||||
|
* @param requiresAuthenticationRequestMatcher the {@link RequestMatcher} used to determine
|
||||||
|
* if authentication is required. Cannot be null.
|
||||||
|
* @param authenticationManager the {@link AuthenticationManager} used to authenticate an {@link Authentication} object.
|
||||||
|
* Cannot be null.
|
||||||
|
*/
|
||||||
|
protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher,
|
||||||
|
AuthenticationManager authenticationManager) {
|
||||||
|
setRequiresAuthenticationRequestMatcher(requiresAuthenticationRequestMatcher);
|
||||||
|
setAuthenticationManager(authenticationManager);
|
||||||
|
}
|
||||||
|
|
||||||
// ~ Methods
|
// ~ Methods
|
||||||
// ========================================================================================================
|
// ========================================================================================================
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package org.springframework.security.web.authentication;
|
package org.springframework.security.web.authentication;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@ -51,6 +52,8 @@ public class UsernamePasswordAuthenticationFilter extends
|
|||||||
|
|
||||||
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
|
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
|
||||||
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
|
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
|
||||||
|
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER =
|
||||||
|
new AntPathRequestMatcher("/login", "POST");
|
||||||
|
|
||||||
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
|
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
|
||||||
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
|
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
|
||||||
@ -60,7 +63,11 @@ public class UsernamePasswordAuthenticationFilter extends
|
|||||||
// ===================================================================================================
|
// ===================================================================================================
|
||||||
|
|
||||||
public UsernamePasswordAuthenticationFilter() {
|
public UsernamePasswordAuthenticationFilter() {
|
||||||
super(new AntPathRequestMatcher("/login", "POST"));
|
super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager) {
|
||||||
|
super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~ Methods
|
// ~ Methods
|
||||||
|
@ -50,6 +50,8 @@ import org.springframework.security.web.authentication.rememberme.AbstractRememb
|
|||||||
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
|
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
|
||||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||||
import org.springframework.security.web.firewall.DefaultHttpFirewall;
|
import org.springframework.security.web.firewall.DefaultHttpFirewall;
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,6 +214,78 @@ public class AbstractAuthenticationProcessingFilterTests {
|
|||||||
assertThat(request.getSession()).isEqualTo(sessionPreAuth);
|
assertThat(request.getSession()).isEqualTo(sessionPreAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNormalOperationWithDefaultFilterProcessesUrlAndAuthenticationManager() throws Exception {
|
||||||
|
// Setup our HTTP request
|
||||||
|
MockHttpServletRequest request = createMockAuthenticationRequest();
|
||||||
|
HttpSession sessionPreAuth = request.getSession();
|
||||||
|
|
||||||
|
// Setup our filter configuration
|
||||||
|
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||||
|
|
||||||
|
// Setup our expectation that the filter chain will not be invoked, as we redirect
|
||||||
|
// to defaultTargetUrl
|
||||||
|
MockFilterChain chain = new MockFilterChain(false);
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
// Setup our test object, to grant access
|
||||||
|
MockAuthenticationFilter filter = new MockAuthenticationFilter(
|
||||||
|
"/j_mock_post", mock(AuthenticationManager.class));
|
||||||
|
|
||||||
|
filter.setSessionAuthenticationStrategy(
|
||||||
|
mock(SessionAuthenticationStrategy.class));
|
||||||
|
filter.setAuthenticationSuccessHandler(successHandler);
|
||||||
|
filter.setAuthenticationFailureHandler(failureHandler);
|
||||||
|
filter.afterPropertiesSet();
|
||||||
|
|
||||||
|
// Test
|
||||||
|
filter.doFilter(request, response, chain);
|
||||||
|
assertThat(response.getRedirectedUrl()).isEqualTo("/mycontext/logged_in.jsp");
|
||||||
|
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull();
|
||||||
|
assertThat(
|
||||||
|
SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()).isEqualTo(
|
||||||
|
"test");
|
||||||
|
// Should still have the same session
|
||||||
|
assertThat(request.getSession()).isEqualTo(sessionPreAuth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNormalOperationWithRequestMatcherAndAuthenticationManager() throws Exception {
|
||||||
|
// Setup our HTTP request
|
||||||
|
MockHttpServletRequest request = createMockAuthenticationRequest();
|
||||||
|
request.setServletPath("/j_eradicate_corona_virus");
|
||||||
|
request.setRequestURI("/mycontext/j_eradicate_corona_virus");
|
||||||
|
HttpSession sessionPreAuth = request.getSession();
|
||||||
|
|
||||||
|
// Setup our filter configuration
|
||||||
|
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||||
|
|
||||||
|
// Setup our expectation that the filter chain will not be invoked, as we redirect
|
||||||
|
// to defaultTargetUrl
|
||||||
|
MockFilterChain chain = new MockFilterChain(false);
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
// Setup our test object, to grant access
|
||||||
|
MockAuthenticationFilter filter = new MockAuthenticationFilter(
|
||||||
|
new AntPathRequestMatcher("/j_eradicate_corona_virus"), mock(AuthenticationManager.class));
|
||||||
|
|
||||||
|
filter.setSessionAuthenticationStrategy(
|
||||||
|
mock(SessionAuthenticationStrategy.class));
|
||||||
|
filter.setAuthenticationSuccessHandler(successHandler);
|
||||||
|
filter.setAuthenticationFailureHandler(failureHandler);
|
||||||
|
filter.afterPropertiesSet();
|
||||||
|
|
||||||
|
// Test
|
||||||
|
filter.doFilter(request, response, chain);
|
||||||
|
assertThat(response.getRedirectedUrl()).isEqualTo("/mycontext/logged_in.jsp");
|
||||||
|
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull();
|
||||||
|
assertThat(
|
||||||
|
SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()).isEqualTo(
|
||||||
|
"test");
|
||||||
|
// Should still have the same session
|
||||||
|
assertThat(request.getSession()).isEqualTo(sessionPreAuth);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartupDetectsInvalidAuthenticationManager() {
|
public void testStartupDetectsInvalidAuthenticationManager() {
|
||||||
AbstractAuthenticationProcessingFilter filter = new MockAuthenticationFilter();
|
AbstractAuthenticationProcessingFilter filter = new MockAuthenticationFilter();
|
||||||
@ -430,20 +504,33 @@ public class AbstractAuthenticationProcessingFilterTests {
|
|||||||
private class MockAuthenticationFilter
|
private class MockAuthenticationFilter
|
||||||
extends AbstractAuthenticationProcessingFilter {
|
extends AbstractAuthenticationProcessingFilter {
|
||||||
|
|
||||||
|
private static final String DEFAULT_FILTER_PROCESSING_URL = "/j_mock_post";
|
||||||
|
|
||||||
private AuthenticationException exceptionToThrow;
|
private AuthenticationException exceptionToThrow;
|
||||||
|
|
||||||
private boolean grantAccess;
|
private boolean grantAccess;
|
||||||
|
|
||||||
MockAuthenticationFilter(boolean grantAccess) {
|
MockAuthenticationFilter(boolean grantAccess) {
|
||||||
this();
|
this();
|
||||||
setRememberMeServices(new NullRememberMeServices());
|
setupRememberMeServicesAndAuthenticationException();
|
||||||
this.grantAccess = grantAccess;
|
this.grantAccess = grantAccess;
|
||||||
this.exceptionToThrow = new BadCredentialsException(
|
|
||||||
"Mock requested to do so");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MockAuthenticationFilter() {
|
private MockAuthenticationFilter() {
|
||||||
super("/j_mock_post");
|
super(DEFAULT_FILTER_PROCESSING_URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MockAuthenticationFilter(String defaultFilterProcessingUrl, AuthenticationManager authenticationManager) {
|
||||||
|
super(defaultFilterProcessingUrl, authenticationManager);
|
||||||
|
setupRememberMeServicesAndAuthenticationException();
|
||||||
|
this.grantAccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MockAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher,
|
||||||
|
AuthenticationManager authenticationManager) {
|
||||||
|
super(requiresAuthenticationRequestMatcher, authenticationManager);
|
||||||
|
setupRememberMeServicesAndAuthenticationException();
|
||||||
|
this.grantAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication attemptAuthentication(HttpServletRequest request,
|
public Authentication attemptAuthentication(HttpServletRequest request,
|
||||||
@ -456,6 +543,13 @@ public class AbstractAuthenticationProcessingFilterTests {
|
|||||||
throw exceptionToThrow;
|
throw exceptionToThrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupRememberMeServicesAndAuthenticationException() {
|
||||||
|
setRememberMeServices(new NullRememberMeServices());
|
||||||
|
this.exceptionToThrow = new BadCredentialsException(
|
||||||
|
"Mock requested to do so");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MockFilterChain implements FilterChain {
|
private class MockFilterChain implements FilterChain {
|
||||||
|
@ -57,6 +57,23 @@ public class UsernamePasswordAuthenticationFilterTests {
|
|||||||
assertThat(((WebAuthenticationDetails) result.getDetails()).getRemoteAddress()).isEqualTo("127.0.0.1");
|
assertThat(((WebAuthenticationDetails) result.getDetails()).getRemoteAddress()).isEqualTo("127.0.0.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstructorInjectionOfAuthenticationManager() {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||||
|
request.addParameter(
|
||||||
|
UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY,
|
||||||
|
"rod");
|
||||||
|
request.addParameter(
|
||||||
|
UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY,
|
||||||
|
"dokdo");
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationFilter filter =
|
||||||
|
new UsernamePasswordAuthenticationFilter(createAuthenticationManager());
|
||||||
|
|
||||||
|
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullPasswordHandledGracefully() {
|
public void testNullPasswordHandledGracefully() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user