1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Change default SecurityContextRepository

Save SecurityContext in request attributes for stateless session
management using RequestAttributeSecurityContextRepository.

Closes gh-11026
This commit is contained in:
Steve Riesenberg
2022-09-21 11:21:19 -05:00
parent ccac34b07c
commit 3c66ef6305
17 changed files with 108 additions and 20 deletions
@@ -47,7 +47,7 @@ import org.springframework.security.web.authentication.session.RegisterSessionAu
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.NullSecurityContextRepository;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.savedrequest.NullRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
@@ -341,7 +341,7 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
boolean stateless = isStateless();
if (securityContextRepository == null) {
if (stateless) {
http.setSharedObject(SecurityContextRepository.class, new NullSecurityContextRepository());
http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository());
}
else {
HttpSessionSecurityContextRepository httpSecurityRepository = new HttpSessionSecurityContextRepository();
@@ -61,7 +61,7 @@ import org.springframework.security.web.authentication.session.ConcurrentSession
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.NullSecurityContextRepository;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextHolderFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
@@ -365,7 +365,7 @@ class HttpConfigurationBuilder {
if (!StringUtils.hasText(repoRef)) {
BeanDefinitionBuilder contextRepo;
if (this.sessionPolicy == SessionCreationPolicy.STATELESS) {
contextRepo = BeanDefinitionBuilder.rootBeanDefinition(NullSecurityContextRepository.class);
contextRepo = BeanDefinitionBuilder.rootBeanDefinition(RequestAttributeSecurityContextRepository.class);
}
else {
contextRepo = BeanDefinitionBuilder.rootBeanDefinition(HttpSessionSecurityContextRepository.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ import org.springframework.security.web.authentication.session.ChangeSessionIdAu
import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.session.ConcurrentSessionFilter;
@@ -340,6 +341,22 @@ public class SessionManagementConfigurerTests {
this.mvc.perform(get("/")).andExpect(content().string("encoded"));
}
@Test
public void loginWhenSessionCreationPolicyStatelessThenSecurityContextIsAvailableInRequestAttributes()
throws Exception {
this.spring.register(HttpBasicSessionCreationPolicyStatelessConfig.class).autowire();
// @formatter:off
MvcResult mvcResult = this.mvc.perform(get("/").with(httpBasic("user", "password")))
.andExpect(status().isOk())
.andReturn();
// @formatter:on
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
SecurityContext securityContext = (SecurityContext) mvcResult.getRequest()
.getAttribute(RequestAttributeSecurityContextRepository.DEFAULT_REQUEST_ATTR_NAME);
assertThat(securityContext).isNotNull();
}
@Configuration
@EnableWebSecurity
static class SessionManagementRequestCacheConfig extends WebSecurityConfigurerAdapter {
@@ -659,6 +676,38 @@ public class SessionManagementConfigurerTests {
}
@Configuration
@EnableWebSecurity
static class HttpBasicSessionCreationPolicyStatelessConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement((sessionManagement) ->
sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.httpBasic(withDefaults());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
@Bean
EncodesUrls encodesUrls() {
return new EncodesUrls();
}
}
@RestController
static class EncodesUrls {