Allow configuring SecurityContextRepository for BasicAuthenticationFilter
Closes gh-12031
This commit is contained in:
parent
b237d7ee38
commit
59829321a8
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -36,6 +36,8 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
|
||||||
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||||
|
import org.springframework.security.web.context.SecurityContextRepository;
|
||||||
import org.springframework.security.web.util.matcher.AndRequestMatcher;
|
import org.springframework.security.web.util.matcher.AndRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
|
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
|
||||||
|
@ -75,6 +77,7 @@ import org.springframework.web.accept.HeaderContentNegotiationStrategy;
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
* @author Evgeniy Cheban
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
|
@ -91,6 +94,8 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
|
|
||||||
private BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
|
private BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
|
||||||
|
|
||||||
|
private SecurityContextRepository securityContextRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
* @see HttpSecurity#httpBasic()
|
* @see HttpSecurity#httpBasic()
|
||||||
|
@ -142,6 +147,19 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a custom {@link SecurityContextRepository} to use for basic
|
||||||
|
* authentication. The default is {@link RequestAttributeSecurityContextRepository}.
|
||||||
|
* @param securityContextRepository the custom {@link SecurityContextRepository} to
|
||||||
|
* use
|
||||||
|
* @return {@link HttpBasicConfigurer} for additional customization
|
||||||
|
* @since 6.1
|
||||||
|
*/
|
||||||
|
public HttpBasicConfigurer<B> securityContextRepository(SecurityContextRepository securityContextRepository) {
|
||||||
|
this.securityContextRepository = securityContextRepository;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(B http) {
|
public void init(B http) {
|
||||||
registerDefaults(http);
|
registerDefaults(http);
|
||||||
|
@ -195,6 +213,9 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
if (this.authenticationDetailsSource != null) {
|
if (this.authenticationDetailsSource != null) {
|
||||||
basicAuthenticationFilter.setAuthenticationDetailsSource(this.authenticationDetailsSource);
|
basicAuthenticationFilter.setAuthenticationDetailsSource(this.authenticationDetailsSource);
|
||||||
}
|
}
|
||||||
|
if (this.securityContextRepository != null) {
|
||||||
|
basicAuthenticationFilter.setSecurityContextRepository(this.securityContextRepository);
|
||||||
|
}
|
||||||
RememberMeServices rememberMeServices = http.getSharedObject(RememberMeServices.class);
|
RememberMeServices rememberMeServices = http.getSharedObject(RememberMeServices.class);
|
||||||
if (rememberMeServices != null) {
|
if (rememberMeServices != null) {
|
||||||
basicAuthenticationFilter.setRememberMeServices(rememberMeServices);
|
basicAuthenticationFilter.setRememberMeServices(rememberMeServices);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -34,6 +34,7 @@ import org.springframework.security.config.test.SpringTestContext;
|
||||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextChangedListener;
|
import org.springframework.security.core.context.SecurityContextChangedListener;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
@ -42,6 +43,7 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
import org.springframework.security.web.context.SecurityContextRepository;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -66,6 +68,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
* @author Eleftheria Stein
|
* @author Eleftheria Stein
|
||||||
|
* @author Evgeniy Cheban
|
||||||
*/
|
*/
|
||||||
@ExtendWith(SpringTestContextExtension.class)
|
@ExtendWith(SpringTestContextExtension.class)
|
||||||
public class HttpBasicConfigurerTests {
|
public class HttpBasicConfigurerTests {
|
||||||
|
@ -145,6 +148,15 @@ public class HttpBasicConfigurerTests {
|
||||||
verify(listener).securityContextChanged(setAuthentication(UsernamePasswordAuthenticationToken.class));
|
verify(listener).securityContextChanged(setAuthentication(UsernamePasswordAuthenticationToken.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void httpBasicWhenUsingCustomSecurityContextRepositoryThenUses() throws Exception {
|
||||||
|
this.spring.register(CustomSecurityContextRepositoryConfig.class, Users.class, Home.class).autowire();
|
||||||
|
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isOk())
|
||||||
|
.andExpect(content().string("user"));
|
||||||
|
verify(CustomSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPOSITORY)
|
||||||
|
.saveContext(any(SecurityContext.class), any(HttpServletRequest.class), any(HttpServletResponse.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class ObjectPostProcessorConfig {
|
static class ObjectPostProcessorConfig {
|
||||||
|
@ -321,6 +333,24 @@ public class HttpBasicConfigurerTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class CustomSecurityContextRepositoryConfig {
|
||||||
|
|
||||||
|
static final SecurityContextRepository SECURITY_CONTEXT_REPOSITORY = mock(SecurityContextRepository.class);
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.httpBasic()
|
||||||
|
.securityContextRepository(SECURITY_CONTEXT_REPOSITORY);
|
||||||
|
// @formatter:on
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class Users {
|
static class Users {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue