mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-17 07:43:30 +00:00
Default Require Explicit Save SecurityContext
Closes gh-11762
This commit is contained in:
parent
b1fd9af723
commit
2efc8dcd15
@ -323,7 +323,7 @@ class HttpConfigurationBuilder {
|
|||||||
|
|
||||||
private boolean isExplicitSave() {
|
private boolean isExplicitSave() {
|
||||||
String explicitSaveAttr = this.httpElt.getAttribute(ATT_SECURITY_CONTEXT_EXPLICIT_SAVE);
|
String explicitSaveAttr = this.httpElt.getAttribute(ATT_SECURITY_CONTEXT_EXPLICIT_SAVE);
|
||||||
return Boolean.parseBoolean(explicitSaveAttr);
|
return !StringUtils.hasText(explicitSaveAttr) || Boolean.parseBoolean(explicitSaveAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createForceEagerSessionCreationFilter() {
|
private void createForceEagerSessionCreationFilter() {
|
||||||
|
@ -105,10 +105,6 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser {
|
|||||||
.addConstructorArgValue(clientRegistrationRepository).addConstructorArgValue(authorizedClientRepository)
|
.addConstructorArgValue(clientRegistrationRepository).addConstructorArgValue(authorizedClientRepository)
|
||||||
.addConstructorArgValue(this.authenticationManager)
|
.addConstructorArgValue(this.authenticationManager)
|
||||||
.addPropertyValue("authorizationRequestRepository", authorizationRequestRepository);
|
.addPropertyValue("authorizationRequestRepository", authorizationRequestRepository);
|
||||||
if (this.authenticationFilterSecurityContextRepositoryRef != null) {
|
|
||||||
authorizationCodeGrantFilterBldr.addPropertyValue("securityContextRepository",
|
|
||||||
this.authenticationFilterSecurityContextRepositoryRef);
|
|
||||||
}
|
|
||||||
this.authorizationCodeGrantFilter = authorizationCodeGrantFilterBldr.getBeanDefinition();
|
this.authorizationCodeGrantFilter = authorizationCodeGrantFilterBldr.getBeanDefinition();
|
||||||
|
|
||||||
BeanMetadataElement accessTokenResponseClient = getAccessTokenResponseClient(authorizationCodeGrantElt);
|
BeanMetadataElement accessTokenResponseClient = getAccessTokenResponseClient(authorizationCodeGrantElt);
|
||||||
|
@ -354,7 +354,7 @@ http.attlist &=
|
|||||||
## A reference to a SecurityContextRepository bean. This can be used to customize how the SecurityContext is stored between requests.
|
## A reference to a SecurityContextRepository bean. This can be used to customize how the SecurityContext is stored between requests.
|
||||||
attribute security-context-repository-ref {xsd:token}?
|
attribute security-context-repository-ref {xsd:token}?
|
||||||
http.attlist &=
|
http.attlist &=
|
||||||
## Optional attribute that specifies that the SecurityContext should require explicit saving rather than being synchronized from the SecurityContextHolder. Defaults to "false".
|
## Optional attribute that specifies that the SecurityContext should require explicit saving rather than being synchronized from the SecurityContextHolder. Defaults to "true".
|
||||||
attribute security-context-explicit-save {xsd:boolean}?
|
attribute security-context-explicit-save {xsd:boolean}?
|
||||||
http.attlist &=
|
http.attlist &=
|
||||||
request-matcher?
|
request-matcher?
|
||||||
|
@ -82,9 +82,6 @@ public class DeferHttpSessionJavaConfigTests {
|
|||||||
csrfRepository.setDeferLoadToken(true);
|
csrfRepository.setDeferLoadToken(true);
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
http
|
http
|
||||||
.securityContext((securityContext) -> securityContext
|
|
||||||
.requireExplicitSave(true)
|
|
||||||
)
|
|
||||||
.authorizeHttpRequests((requests) -> requests
|
.authorizeHttpRequests((requests) -> requests
|
||||||
.anyRequest().permitAll()
|
.anyRequest().permitAll()
|
||||||
)
|
)
|
||||||
|
@ -93,7 +93,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera
|
|||||||
import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
|
import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
import org.springframework.security.web.context.HttpRequestResponseHolder;
|
import org.springframework.security.web.context.HttpRequestResponseHolder;
|
||||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||||
import org.springframework.security.web.context.SecurityContextRepository;
|
import org.springframework.security.web.context.SecurityContextRepository;
|
||||||
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
|
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
|
||||||
import org.springframework.security.web.csrf.CsrfFilter;
|
import org.springframework.security.web.csrf.CsrfFilter;
|
||||||
@ -356,7 +356,7 @@ public class MiscHttpConfigTests {
|
|||||||
List<Filter> filters = getFilters("/");
|
List<Filter> filters = getFilters("/");
|
||||||
Class<?> userFilterClass = this.spring.getContext().getBean("userFilter").getClass();
|
Class<?> userFilterClass = this.spring.getContext().getBean("userFilter").getClass();
|
||||||
assertThat(filters).extracting((Extractor<Filter, Class<?>>) (filter) -> filter.getClass()).containsSubsequence(
|
assertThat(filters).extracting((Extractor<Filter, Class<?>>) (filter) -> filter.getClass()).containsSubsequence(
|
||||||
userFilterClass, userFilterClass, SecurityContextPersistenceFilter.class, LogoutFilter.class,
|
userFilterClass, userFilterClass, SecurityContextHolderFilter.class, LogoutFilter.class,
|
||||||
userFilterClass);
|
userFilterClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +472,7 @@ public class MiscHttpConfigTests {
|
|||||||
this.spring.configLocations(xml("SecurityContextRepository")).autowire();
|
this.spring.configLocations(xml("SecurityContextRepository")).autowire();
|
||||||
SecurityContextRepository repository = this.spring.getContext().getBean(SecurityContextRepository.class);
|
SecurityContextRepository repository = this.spring.getContext().getBean(SecurityContextRepository.class);
|
||||||
SecurityContext context = new SecurityContextImpl(new TestingAuthenticationToken("user", "password"));
|
SecurityContext context = new SecurityContextImpl(new TestingAuthenticationToken("user", "password"));
|
||||||
given(repository.loadContext(any(HttpRequestResponseHolder.class))).willReturn(context);
|
given(repository.loadContext(any(HttpServletRequest.class))).willReturn(() -> context);
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
MvcResult result = this.mvc.perform(get("/protected").with(userCredentials()))
|
MvcResult result = this.mvc.perform(get("/protected").with(userCredentials()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@ -839,7 +839,7 @@ public class MiscHttpConfigTests {
|
|||||||
private void assertThatFiltersMatchExpectedAutoConfigList(String url) {
|
private void assertThatFiltersMatchExpectedAutoConfigList(String url) {
|
||||||
Iterator<Filter> filters = getFilters(url).iterator();
|
Iterator<Filter> filters = getFilters(url).iterator();
|
||||||
assertThat(filters.next()).isInstanceOf(DisableEncodeUrlFilter.class);
|
assertThat(filters.next()).isInstanceOf(DisableEncodeUrlFilter.class);
|
||||||
assertThat(filters.next()).isInstanceOf(SecurityContextPersistenceFilter.class);
|
assertThat(filters.next()).isInstanceOf(SecurityContextHolderFilter.class);
|
||||||
assertThat(filters.next()).isInstanceOf(WebAsyncManagerIntegrationFilter.class);
|
assertThat(filters.next()).isInstanceOf(WebAsyncManagerIntegrationFilter.class);
|
||||||
assertThat(filters.next()).isInstanceOf(HeaderWriterFilter.class);
|
assertThat(filters.next()).isInstanceOf(HeaderWriterFilter.class);
|
||||||
assertThat(filters.next()).isInstanceOf(CsrfFilter.class);
|
assertThat(filters.next()).isInstanceOf(CsrfFilter.class);
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
<b:bean class="org.springframework.security.config.http.DeferHttpSessionXmlConfigTests$Service" />
|
<b:bean class="org.springframework.security.config.http.DeferHttpSessionXmlConfigTests$Service" />
|
||||||
|
|
||||||
<http auto-config="true"
|
<http auto-config="true"
|
||||||
security-context-explicit-save="true"
|
|
||||||
use-authorization-manager="true">
|
use-authorization-manager="true">
|
||||||
<intercept-url pattern="/**" access="permitAll"/>
|
<intercept-url pattern="/**" access="permitAll"/>
|
||||||
<csrf request-attribute-name="_csrf"
|
<csrf request-attribute-name="_csrf"
|
||||||
|
@ -45,6 +45,7 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
|||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
|
import org.springframework.security.web.context.SecurityContextRepository;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@ -92,8 +93,11 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
|
|||||||
|
|
||||||
private List<LogoutHandler> logoutHandlers;
|
private List<LogoutHandler> logoutHandlers;
|
||||||
|
|
||||||
HttpServlet3RequestFactory(String rolePrefix) {
|
private SecurityContextRepository securityContextRepository;
|
||||||
|
|
||||||
|
HttpServlet3RequestFactory(String rolePrefix, SecurityContextRepository securityContextRepository) {
|
||||||
this.rolePrefix = rolePrefix;
|
this.rolePrefix = rolePrefix;
|
||||||
|
this.securityContextRepository = securityContextRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,6 +248,7 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
|
|||||||
.createEmptyContext();
|
.createEmptyContext();
|
||||||
context.setAuthentication(authentication);
|
context.setAuthentication(authentication);
|
||||||
HttpServlet3RequestFactory.this.securityContextHolderStrategy.setContext(context);
|
HttpServlet3RequestFactory.this.securityContextHolderStrategy.setContext(context);
|
||||||
|
HttpServlet3RequestFactory.this.securityContextRepository.saveContext(context, this, this.response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
|
private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
|
||||||
|
@ -35,6 +35,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
|
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||||
|
import org.springframework.security.web.context.SecurityContextRepository;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
import org.springframework.web.filter.GenericFilterBean;
|
||||||
|
|
||||||
@ -84,6 +86,18 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||||||
|
|
||||||
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||||
|
|
||||||
|
private SecurityContextRepository securityContextRepository = new HttpSessionSecurityContextRepository();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SecurityContextRepository} to use. The default is to use {@link HttpSessionSecurityContextRepository}.
|
||||||
|
* @param securityContextRepository the {@link SecurityContextRepository} to use.
|
||||||
|
* @since 6.0
|
||||||
|
*/
|
||||||
|
public void setSecurityContextRepository(SecurityContextRepository securityContextRepository) {
|
||||||
|
Assert.notNull(securityContextRepository, "securityContextRepository cannot be null");
|
||||||
|
this.securityContextRepository = securityContextRepository;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
|
* Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
|
||||||
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
|
* the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
|
||||||
@ -188,7 +202,7 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HttpServletRequestFactory createServlet3Factory(String rolePrefix) {
|
private HttpServletRequestFactory createServlet3Factory(String rolePrefix) {
|
||||||
HttpServlet3RequestFactory factory = new HttpServlet3RequestFactory(rolePrefix);
|
HttpServlet3RequestFactory factory = new HttpServlet3RequestFactory(rolePrefix, this.securityContextRepository);
|
||||||
factory.setTrustResolver(this.trustResolver);
|
factory.setTrustResolver(this.trustResolver);
|
||||||
factory.setAuthenticationEntryPoint(this.authenticationEntryPoint);
|
factory.setAuthenticationEntryPoint(this.authenticationEntryPoint);
|
||||||
factory.setAuthenticationManager(this.authenticationManager);
|
factory.setAuthenticationManager(this.authenticationManager);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user