Skip to content

Add constructors receiving AuthenticationManager #8362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ protected AbstractAuthenticationProcessingFilter(
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
// ========================================================================================================

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.security.web.authentication;

import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
Expand Down Expand Up @@ -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_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 passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
Expand All @@ -60,7 +63,11 @@ public class UsernamePasswordAuthenticationFilter extends
// ===================================================================================================

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
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;

/**
Expand Down Expand Up @@ -212,6 +214,78 @@ public void testNormalOperationWithDefaultFilterProcessesUrl() throws Exception
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
public void testStartupDetectsInvalidAuthenticationManager() {
AbstractAuthenticationProcessingFilter filter = new MockAuthenticationFilter();
Expand Down Expand Up @@ -430,20 +504,33 @@ public void setRememberMeServicesShouldntAllowNulls() {
private class MockAuthenticationFilter
extends AbstractAuthenticationProcessingFilter {

private static final String DEFAULT_FILTER_PROCESSING_URL = "/j_mock_post";

private AuthenticationException exceptionToThrow;

private boolean grantAccess;

MockAuthenticationFilter(boolean grantAccess) {
this();
setRememberMeServices(new NullRememberMeServices());
setupRememberMeServicesAndAuthenticationException();
this.grantAccess = grantAccess;
this.exceptionToThrow = new BadCredentialsException(
"Mock requested to do so");
}

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,
Expand All @@ -456,6 +543,13 @@ public Authentication attemptAuthentication(HttpServletRequest request,
throw exceptionToThrow;
}
}

private void setupRememberMeServicesAndAuthenticationException() {
setRememberMeServices(new NullRememberMeServices());
this.exceptionToThrow = new BadCredentialsException(
"Mock requested to do so");
}

}

private class MockFilterChain implements FilterChain {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@ public void testNormalOperation() {
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
public void testNullPasswordHandledGracefully() {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
Expand Down