Add SecurityContextRepository to all Authentication Filters
Closes gh-10949
This commit is contained in:
		
						commit
						d2f24ae5f5
					
				| 
						 | 
				
			
			@ -42,6 +42,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		|||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
 | 
			
		||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
| 
						 | 
				
			
			@ -205,6 +207,8 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
 | 
			
		|||
 | 
			
		||||
	private AuthenticationFailureHandler proxyFailureHandler = new SimpleUrlAuthenticationFailureHandler();
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	public CasAuthenticationFilter() {
 | 
			
		||||
		super("/login/cas");
 | 
			
		||||
		setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler());
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +227,7 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
 | 
			
		|||
		SecurityContext context = SecurityContextHolder.createEmptyContext();
 | 
			
		||||
		context.setAuthentication(authResult);
 | 
			
		||||
		SecurityContextHolder.setContext(context);
 | 
			
		||||
		this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
		if (this.eventPublisher != null) {
 | 
			
		||||
			this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -274,6 +279,18 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
 | 
			
		|||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link AuthenticationFailureHandler} for proxy requests.
 | 
			
		||||
	 * @param proxyFailureHandler
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ import javax.servlet.FilterChain;
 | 
			
		|||
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
 | 
			
		||||
import org.junit.jupiter.api.AfterEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletResponse;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,12 +33,15 @@ import org.springframework.security.cas.ServiceProperties;
 | 
			
		|||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.AuthenticationException;
 | 
			
		||||
import org.springframework.security.core.authority.AuthorityUtils;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.any;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +186,38 @@ public class CasAuthenticationFilterTests {
 | 
			
		|||
		verify(successHandler).onAuthenticationSuccess(request, response, authentication);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testSecurityContextHolder() throws Exception {
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		AuthenticationManager manager = mock(AuthenticationManager.class);
 | 
			
		||||
		Authentication authentication = new TestingAuthenticationToken("un", "pwd", "ROLE_USER");
 | 
			
		||||
		given(manager.authenticate(any(Authentication.class))).willReturn(authentication);
 | 
			
		||||
		ServiceProperties serviceProperties = new ServiceProperties();
 | 
			
		||||
		serviceProperties.setAuthenticateAllArtifacts(true);
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setParameter("ticket", "ST-1-123");
 | 
			
		||||
		request.setServletPath("/authenticate");
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		FilterChain chain = mock(FilterChain.class);
 | 
			
		||||
		CasAuthenticationFilter filter = new CasAuthenticationFilter();
 | 
			
		||||
		filter.setServiceProperties(serviceProperties);
 | 
			
		||||
		filter.setProxyGrantingTicketStorage(mock(ProxyGrantingTicketStorage.class));
 | 
			
		||||
		filter.setAuthenticationManager(manager);
 | 
			
		||||
		filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		filter.afterPropertiesSet();
 | 
			
		||||
		filter.doFilter(request, response, chain);
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull()
 | 
			
		||||
				.withFailMessage("Authentication should not be null");
 | 
			
		||||
		verify(chain).doFilter(request, response);
 | 
			
		||||
		// validate for when the filterProcessUrl matches
 | 
			
		||||
		filter.setFilterProcessesUrl(request.getServletPath());
 | 
			
		||||
		SecurityContextHolder.clearContext();
 | 
			
		||||
		filter.doFilter(request, response, chain);
 | 
			
		||||
		ArgumentCaptor<SecurityContext> contextArg = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		verify(securityContextRepository).saveContext(contextArg.capture(), eq(request), eq(response));
 | 
			
		||||
		assertThat(contextArg.getValue().getAuthentication().getPrincipal()).isEqualTo(authentication.getName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// SEC-1592
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testChainNotInvokedForProxyReceptor() throws Exception {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,8 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
 | 
			
		|||
import org.springframework.security.web.AuthenticationEntryPoint;
 | 
			
		||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.web.filter.OncePerRequestFilter;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +77,8 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter
 | 
			
		|||
 | 
			
		||||
	private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct a {@code BearerTokenAuthenticationFilter} using the provided parameter(s)
 | 
			
		||||
	 * @param authenticationManagerResolver
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +135,7 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter
 | 
			
		|||
			SecurityContext context = SecurityContextHolder.createEmptyContext();
 | 
			
		||||
			context.setAuthentication(authenticationResult);
 | 
			
		||||
			SecurityContextHolder.setContext(context);
 | 
			
		||||
			this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
			if (this.logger.isDebugEnabled()) {
 | 
			
		||||
				this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authenticationResult));
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +148,18 @@ public final class BearerTokenAuthenticationFilter extends OncePerRequestFilter
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the {@link BearerTokenResolver} to use. Defaults to
 | 
			
		||||
	 * {@link DefaultBearerTokenResolver}.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,18 +36,23 @@ import org.springframework.security.authentication.AuthenticationDetailsSource;
 | 
			
		|||
import org.springframework.security.authentication.AuthenticationManager;
 | 
			
		||||
import org.springframework.security.authentication.AuthenticationManagerResolver;
 | 
			
		||||
import org.springframework.security.authentication.AuthenticationServiceException;
 | 
			
		||||
import org.springframework.security.authentication.TestingAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 | 
			
		||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
 | 
			
		||||
import org.springframework.security.oauth2.server.resource.BearerTokenError;
 | 
			
		||||
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
 | 
			
		||||
import org.springframework.security.web.AuthenticationEntryPoint;
 | 
			
		||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.any;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +107,26 @@ public class BearerTokenAuthenticationFilterTests {
 | 
			
		|||
		assertThat(captor.getValue().getPrincipal()).isEqualTo("token");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void doFilterWhenSecurityContextRepositoryThenSaves() throws ServletException, IOException {
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		String token = "token";
 | 
			
		||||
		given(this.bearerTokenResolver.resolve(this.request)).willReturn(token);
 | 
			
		||||
		TestingAuthenticationToken expectedAuthentication = new TestingAuthenticationToken("test", "password");
 | 
			
		||||
		given(this.authenticationManager.authenticate(any())).willReturn(expectedAuthentication);
 | 
			
		||||
		BearerTokenAuthenticationFilter filter = addMocks(
 | 
			
		||||
				new BearerTokenAuthenticationFilter(this.authenticationManager));
 | 
			
		||||
		filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		filter.doFilter(this.request, this.response, this.filterChain);
 | 
			
		||||
		ArgumentCaptor<BearerTokenAuthenticationToken> captor = ArgumentCaptor
 | 
			
		||||
				.forClass(BearerTokenAuthenticationToken.class);
 | 
			
		||||
		verify(this.authenticationManager).authenticate(captor.capture());
 | 
			
		||||
		assertThat(captor.getValue().getPrincipal()).isEqualTo(token);
 | 
			
		||||
		ArgumentCaptor<SecurityContext> contextArg = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		verify(securityContextRepository).saveContext(contextArg.capture(), eq(this.request), eq(this.response));
 | 
			
		||||
		assertThat(contextArg.getValue().getAuthentication().getName()).isEqualTo(expectedAuthentication.getName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void doFilterWhenUsingAuthenticationManagerResolverThenAuthenticates() throws Exception {
 | 
			
		||||
		BearerTokenAuthenticationFilter filter = addMocks(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,8 @@ import org.springframework.security.core.context.SecurityContext;
 | 
			
		|||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
 | 
			
		||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +136,8 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
 | 
			
		|||
 | 
			
		||||
	private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -314,6 +318,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
 | 
			
		|||
		SecurityContext context = SecurityContextHolder.createEmptyContext();
 | 
			
		||||
		context.setAuthentication(authResult);
 | 
			
		||||
		SecurityContextHolder.setContext(context);
 | 
			
		||||
		this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
		if (this.logger.isDebugEnabled()) {
 | 
			
		||||
			this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -435,6 +440,18 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
 | 
			
		|||
		this.failureHandler = failureHandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected AuthenticationSuccessHandler getSuccessHandler() {
 | 
			
		||||
		return this.successHandler;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,8 @@ import org.springframework.security.core.Authentication;
 | 
			
		|||
import org.springframework.security.core.AuthenticationException;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +76,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
 | 
			
		|||
	private AuthenticationFailureHandler failureHandler = new AuthenticationEntryPointFailureHandler(
 | 
			
		||||
			new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	private AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
 | 
			
		||||
 | 
			
		||||
	public AuthenticationFilter(AuthenticationManager authenticationManager,
 | 
			
		||||
| 
						 | 
				
			
			@ -135,6 +139,18 @@ public class AuthenticationFilter extends OncePerRequestFilter {
 | 
			
		|||
		this.authenticationManagerResolver = authenticationManagerResolver;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
 | 
			
		||||
			throws ServletException, IOException {
 | 
			
		||||
| 
						 | 
				
			
			@ -173,6 +189,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
 | 
			
		|||
		SecurityContext context = SecurityContextHolder.createEmptyContext();
 | 
			
		||||
		context.setAuthentication(authentication);
 | 
			
		||||
		SecurityContextHolder.setContext(context);
 | 
			
		||||
		this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
		this.successHandler.onAuthenticationSuccess(request, response, chain, authentication);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,8 @@ import org.springframework.security.web.WebAttributes;
 | 
			
		|||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.web.filter.GenericFilterBean;
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +106,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
 | 
			
		|||
 | 
			
		||||
	private RequestMatcher requiresAuthenticationRequestMatcher = new PreAuthenticatedProcessingRequestMatcher();
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether all required properties have been set.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +214,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
 | 
			
		|||
		SecurityContext context = SecurityContextHolder.createEmptyContext();
 | 
			
		||||
		context.setAuthentication(authResult);
 | 
			
		||||
		SecurityContextHolder.setContext(context);
 | 
			
		||||
		this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
		if (this.eventPublisher != null) {
 | 
			
		||||
			this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -242,6 +247,18 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
 | 
			
		|||
		this.eventPublisher = anApplicationEventPublisher;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param authenticationDetailsSource The AuthenticationDetailsSource to use
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,8 @@ import org.springframework.security.core.context.SecurityContext;
 | 
			
		|||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.RememberMeServices;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.web.filter.GenericFilterBean;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +75,8 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
 | 
			
		|||
 | 
			
		||||
	private RememberMeServices rememberMeServices;
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	public RememberMeAuthenticationFilter(AuthenticationManager authenticationManager,
 | 
			
		||||
			RememberMeServices rememberMeServices) {
 | 
			
		||||
		Assert.notNull(authenticationManager, "authenticationManager cannot be null");
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +118,7 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
 | 
			
		|||
				onSuccessfulAuthentication(request, response, rememberMeAuth);
 | 
			
		||||
				this.logger.debug(LogMessage.of(() -> "SecurityContextHolder populated with remember-me token: '"
 | 
			
		||||
						+ SecurityContextHolder.getContext().getAuthentication() + "'"));
 | 
			
		||||
				this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
				if (this.eventPublisher != null) {
 | 
			
		||||
					this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
 | 
			
		||||
							SecurityContextHolder.getContext().getAuthentication(), this.getClass()));
 | 
			
		||||
| 
						 | 
				
			
			@ -179,4 +184,16 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
 | 
			
		|||
		this.successHandler = successHandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		|||
import org.springframework.security.web.AuthenticationEntryPoint;
 | 
			
		||||
import org.springframework.security.web.authentication.NullRememberMeServices;
 | 
			
		||||
import org.springframework.security.web.authentication.RememberMeServices;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.web.filter.OncePerRequestFilter;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +105,8 @@ public class BasicAuthenticationFilter extends OncePerRequestFilter {
 | 
			
		|||
 | 
			
		||||
	private BasicAuthenticationConverter authenticationConverter = new BasicAuthenticationConverter();
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Creates an instance which will authenticate against the supplied
 | 
			
		||||
	 * {@code AuthenticationManager} and which will ignore failed authentication attempts,
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +135,18 @@ public class BasicAuthenticationFilter extends OncePerRequestFilter {
 | 
			
		|||
		this.authenticationEntryPoint = authenticationEntryPoint;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void afterPropertiesSet() {
 | 
			
		||||
		Assert.notNull(this.authenticationManager, "An AuthenticationManager is required");
 | 
			
		||||
| 
						 | 
				
			
			@ -161,6 +177,7 @@ public class BasicAuthenticationFilter extends OncePerRequestFilter {
 | 
			
		|||
					this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));
 | 
			
		||||
				}
 | 
			
		||||
				this.rememberMeServices.loginSuccess(request, response, authResult);
 | 
			
		||||
				this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
				onSuccessfulAuthentication(request, response, authResult);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,8 @@ import org.springframework.security.core.userdetails.UserDetailsService;
 | 
			
		|||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 | 
			
		||||
import org.springframework.security.core.userdetails.cache.NullUserCache;
 | 
			
		||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 | 
			
		||||
import org.springframework.security.web.context.NullSecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.filter.GenericFilterBean;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +108,8 @@ public class DigestAuthenticationFilter extends GenericFilterBean implements Mes
 | 
			
		|||
 | 
			
		||||
	private boolean createAuthenticatedToken = false;
 | 
			
		||||
 | 
			
		||||
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void afterPropertiesSet() {
 | 
			
		||||
		Assert.notNull(this.userDetailsService, "A UserDetailsService is required");
 | 
			
		||||
| 
						 | 
				
			
			@ -192,6 +196,7 @@ public class DigestAuthenticationFilter extends GenericFilterBean implements Mes
 | 
			
		|||
		SecurityContext context = SecurityContextHolder.createEmptyContext();
 | 
			
		||||
		context.setAuthentication(authentication);
 | 
			
		||||
		SecurityContextHolder.setContext(context);
 | 
			
		||||
		this.securityContextRepository.saveContext(context, request, response);
 | 
			
		||||
		chain.doFilter(request, response);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -271,6 +276,18 @@ public class DigestAuthenticationFilter extends GenericFilterBean implements Mes
 | 
			
		|||
		this.createAuthenticatedToken = createAuthenticatedToken;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the {@link SecurityContextRepository} to save the {@link SecurityContext} on
 | 
			
		||||
	 * authentication success. The default action is not to save the
 | 
			
		||||
	 * {@link SecurityContext}.
 | 
			
		||||
	 * @param securityContextRepository the {@link SecurityContextRepository} to use.
 | 
			
		||||
	 * Cannot be null.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
 | 
			
		||||
		Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
 | 
			
		||||
		this.securityContextRepository = securityContextRepository;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private class DigestData {
 | 
			
		||||
 | 
			
		||||
		private final String username;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ import org.apache.commons.logging.Log;
 | 
			
		|||
import org.junit.jupiter.api.AfterEach;
 | 
			
		||||
import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.mock.web.MockFilterConfig;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,14 +35,17 @@ import org.springframework.mock.web.MockHttpServletResponse;
 | 
			
		|||
import org.springframework.security.authentication.AuthenticationManager;
 | 
			
		||||
import org.springframework.security.authentication.BadCredentialsException;
 | 
			
		||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
 | 
			
		||||
import org.springframework.security.authentication.TestAuthentication;
 | 
			
		||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.AuthenticationException;
 | 
			
		||||
import org.springframework.security.core.authority.AuthorityUtils;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServicesTests;
 | 
			
		||||
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
 | 
			
		||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.firewall.DefaultHttpFirewall;
 | 
			
		||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
| 
						 | 
				
			
			@ -322,6 +326,37 @@ public class AbstractAuthenticationProcessingFilterTests {
 | 
			
		|||
		assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testSuccessfulAuthenticationThenDefaultDoesNotCreateSession() throws Exception {
 | 
			
		||||
		Authentication authentication = TestAuthentication.authenticatedUser();
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		MockFilterChain chain = new MockFilterChain(false);
 | 
			
		||||
		MockAuthenticationFilter filter = new MockAuthenticationFilter();
 | 
			
		||||
 | 
			
		||||
		filter.successfulAuthentication(request, response, chain, authentication);
 | 
			
		||||
 | 
			
		||||
		assertThat(request.getSession(false)).isNull();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testSuccessfulAuthenticationWhenCustomSecurityContextRepositoryThenAuthenticationSaved()
 | 
			
		||||
			throws Exception {
 | 
			
		||||
		ArgumentCaptor<SecurityContext> contextCaptor = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		SecurityContextRepository repository = mock(SecurityContextRepository.class);
 | 
			
		||||
		Authentication authentication = TestAuthentication.authenticatedUser();
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		MockFilterChain chain = new MockFilterChain(false);
 | 
			
		||||
		MockAuthenticationFilter filter = new MockAuthenticationFilter();
 | 
			
		||||
		filter.setSecurityContextRepository(repository);
 | 
			
		||||
 | 
			
		||||
		filter.successfulAuthentication(request, response, chain, authentication);
 | 
			
		||||
 | 
			
		||||
		verify(repository).saveContext(contextCaptor.capture(), eq(request), eq(response));
 | 
			
		||||
		assertThat(contextCaptor.getValue().getAuthentication()).isEqualTo(authentication);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testFailedAuthenticationInvokesFailureHandler() throws Exception {
 | 
			
		||||
		// Setup our HTTP request
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
 | 
			
		|||
import org.junit.jupiter.api.AfterEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.junit.jupiter.api.extension.ExtendWith;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
import org.mockito.junit.jupiter.MockitoExtension;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +39,9 @@ import org.springframework.security.authentication.AuthenticationManagerResolver
 | 
			
		|||
import org.springframework.security.authentication.BadCredentialsException;
 | 
			
		||||
import org.springframework.security.authentication.TestingAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
| 
						 | 
				
			
			@ -256,4 +259,36 @@ public class AuthenticationFilterTests {
 | 
			
		|||
		assertThat(session.getId()).isNotEqualTo(sessionId);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void filterWhenSuccessfulAuthenticationThenNoSessionCreated() throws Exception {
 | 
			
		||||
		Authentication authentication = new TestingAuthenticationToken("test", "this", "ROLE_USER");
 | 
			
		||||
		given(this.authenticationConverter.convert(any())).willReturn(authentication);
 | 
			
		||||
		given(this.authenticationManager.authenticate(any())).willReturn(authentication);
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		FilterChain chain = new MockFilterChain();
 | 
			
		||||
		AuthenticationFilter filter = new AuthenticationFilter(this.authenticationManager,
 | 
			
		||||
				this.authenticationConverter);
 | 
			
		||||
		filter.doFilter(request, response, chain);
 | 
			
		||||
		assertThat(request.getSession(false)).isNull();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void filterWhenCustomSecurityContextRepositoryAndSuccessfulAuthenticationRepositoryUsed() throws Exception {
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		ArgumentCaptor<SecurityContext> securityContextArg = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		Authentication authentication = new TestingAuthenticationToken("test", "this", "ROLE_USER");
 | 
			
		||||
		given(this.authenticationConverter.convert(any())).willReturn(authentication);
 | 
			
		||||
		given(this.authenticationManager.authenticate(any())).willReturn(authentication);
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		FilterChain chain = new MockFilterChain();
 | 
			
		||||
		AuthenticationFilter filter = new AuthenticationFilter(this.authenticationManager,
 | 
			
		||||
				this.authenticationConverter);
 | 
			
		||||
		filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		filter.doFilter(request, response, chain);
 | 
			
		||||
		verify(securityContextRepository).saveContext(securityContextArg.capture(), eq(request), eq(response));
 | 
			
		||||
		assertThat(securityContextArg.getValue().getAuthentication()).isEqualTo(authentication);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
 | 
			
		|||
import org.junit.jupiter.api.AfterEach;
 | 
			
		||||
import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
import org.mockito.stubbing.Answer;
 | 
			
		||||
 | 
			
		||||
import org.springframework.mock.web.MockFilterChain;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,17 +35,20 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
 | 
			
		|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.authority.AuthorityUtils;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.core.userdetails.User;
 | 
			
		||||
import org.springframework.security.web.WebAttributes;
 | 
			
		||||
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.any;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +214,31 @@ public class AbstractPreAuthenticatedProcessingFilterTests {
 | 
			
		|||
		assertThat(response.getForwardedUrl()).isEqualTo("/forwardUrl");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void securityContextRepository() throws Exception {
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		Object currentPrincipal = "currentUser";
 | 
			
		||||
		TestingAuthenticationToken authRequest = new TestingAuthenticationToken(currentPrincipal, "something",
 | 
			
		||||
				"ROLE_USER");
 | 
			
		||||
		SecurityContextHolder.getContext().setAuthentication(authRequest);
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		MockFilterChain chain = new MockFilterChain();
 | 
			
		||||
		ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter();
 | 
			
		||||
		filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		filter.setAuthenticationSuccessHandler(new ForwardAuthenticationSuccessHandler("/forwardUrl"));
 | 
			
		||||
		filter.setCheckForPrincipalChanges(true);
 | 
			
		||||
		filter.principal = "newUser";
 | 
			
		||||
		AuthenticationManager am = mock(AuthenticationManager.class);
 | 
			
		||||
		given(am.authenticate(any())).willReturn(authRequest);
 | 
			
		||||
		filter.setAuthenticationManager(am);
 | 
			
		||||
		filter.afterPropertiesSet();
 | 
			
		||||
		filter.doFilter(request, response, chain);
 | 
			
		||||
		ArgumentCaptor<SecurityContext> contextArg = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		verify(securityContextRepository).saveContext(contextArg.capture(), eq(request), eq(response));
 | 
			
		||||
		assertThat(contextArg.getValue().getAuthentication().getPrincipal()).isEqualTo(authRequest.getName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void callsAuthenticationFailureHandlerOnFailedAuthentication() throws Exception {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,10 +36,12 @@ import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		|||
import org.springframework.security.web.authentication.NullRememberMeServices;
 | 
			
		||||
import org.springframework.security.web.authentication.RememberMeServices;
 | 
			
		||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.any;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +154,23 @@ public class RememberMeAuthenticationFilterTests {
 | 
			
		|||
		verifyZeroInteractions(fc);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void securityContextRepositoryInvokedIfSet() throws Exception {
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		AuthenticationManager am = mock(AuthenticationManager.class);
 | 
			
		||||
		given(am.authenticate(this.remembered)).willReturn(this.remembered);
 | 
			
		||||
		RememberMeAuthenticationFilter filter = new RememberMeAuthenticationFilter(am,
 | 
			
		||||
				new MockRememberMeServices(this.remembered));
 | 
			
		||||
		filter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/target"));
 | 
			
		||||
		filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		FilterChain fc = mock(FilterChain.class);
 | 
			
		||||
		request.setRequestURI("x");
 | 
			
		||||
		filter.doFilter(request, response, fc);
 | 
			
		||||
		verify(securityContextRepository).saveContext(any(), eq(request), eq(response));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private class MockRememberMeServices implements RememberMeServices {
 | 
			
		||||
 | 
			
		||||
		private Authentication authToReturn;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ import org.apache.commons.codec.binary.Base64;
 | 
			
		|||
import org.junit.jupiter.api.AfterEach;
 | 
			
		||||
import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletResponse;
 | 
			
		||||
| 
						 | 
				
			
			@ -36,8 +37,10 @@ import org.springframework.security.authentication.BadCredentialsException;
 | 
			
		|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.authority.AuthorityUtils;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContext;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.security.web.authentication.WebAuthenticationDetails;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.web.util.WebUtils;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
| 
						 | 
				
			
			@ -364,4 +367,25 @@ public class BasicAuthenticationFilterTests {
 | 
			
		|||
		assertThat(response.getStatus()).isEqualTo(401);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void requestWhenSecurityContextRepository() throws Exception {
 | 
			
		||||
		ArgumentCaptor<SecurityContext> contextArg = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		this.filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		String token = "rod:koala";
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
 | 
			
		||||
		request.setServletPath("/some_file.html");
 | 
			
		||||
		MockHttpServletResponse response = new MockHttpServletResponse();
 | 
			
		||||
		// Test
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
 | 
			
		||||
		FilterChain chain = mock(FilterChain.class);
 | 
			
		||||
		this.filter.doFilter(request, response, chain);
 | 
			
		||||
		verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull();
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication().getName()).isEqualTo("rod");
 | 
			
		||||
		verify(securityContextRepository).saveContext(contextArg.capture(), eq(request), eq(response));
 | 
			
		||||
		assertThat(contextArg.getValue().getAuthentication().getName()).isEqualTo("rod");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ import org.apache.commons.codec.digest.DigestUtils;
 | 
			
		|||
import org.junit.jupiter.api.AfterEach;
 | 
			
		||||
import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletRequest;
 | 
			
		||||
import org.springframework.mock.web.MockHttpServletResponse;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,10 +41,12 @@ import org.springframework.security.core.userdetails.User;
 | 
			
		|||
import org.springframework.security.core.userdetails.UserDetails;
 | 
			
		||||
import org.springframework.security.core.userdetails.UserDetailsService;
 | 
			
		||||
import org.springframework.security.core.userdetails.cache.NullUserCache;
 | 
			
		||||
import org.springframework.security.web.context.SecurityContextRepository;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 | 
			
		||||
import static org.mockito.ArgumentMatchers.eq;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.times;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
| 
						 | 
				
			
			@ -389,4 +392,25 @@ public class DigestAuthenticationFilterTests {
 | 
			
		|||
		assertThat(existingAuthentication).isSameAs(existingContext.getAuthentication());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testSecurityContextRepository() throws Exception {
 | 
			
		||||
		SecurityContextRepository securityContextRepository = mock(SecurityContextRepository.class);
 | 
			
		||||
		ArgumentCaptor<SecurityContext> contextArg = ArgumentCaptor.forClass(SecurityContext.class);
 | 
			
		||||
		String responseDigest = DigestAuthUtils.generateDigest(false, USERNAME, REALM, PASSWORD, "GET", REQUEST_URI,
 | 
			
		||||
				QOP, NONCE, NC, CNONCE);
 | 
			
		||||
		this.request.addHeader("Authorization",
 | 
			
		||||
				createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
 | 
			
		||||
		this.filter.setSecurityContextRepository(securityContextRepository);
 | 
			
		||||
		this.filter.setCreateAuthenticatedToken(true);
 | 
			
		||||
		MockHttpServletResponse response = executeFilterInContainerSimulator(this.filter, this.request, true);
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull();
 | 
			
		||||
		assertThat(((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername())
 | 
			
		||||
				.isEqualTo(USERNAME);
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication().isAuthenticated()).isTrue();
 | 
			
		||||
		assertThat(SecurityContextHolder.getContext().getAuthentication().getAuthorities())
 | 
			
		||||
				.isEqualTo(AuthorityUtils.createAuthorityList("ROLE_ONE", "ROLE_TWO"));
 | 
			
		||||
		verify(securityContextRepository).saveContext(contextArg.capture(), eq(this.request), eq(response));
 | 
			
		||||
		assertThat(contextArg.getValue().getAuthentication().getName()).isEqualTo(USERNAME);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue