From ff3c560c532e51fc6d8837e276fd424370db1608 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Apr 2023 15:21:32 +0000 Subject: [PATCH 1/3] Release 6.0.3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 18b18d2c9be..e4662024623 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ springBootVersion=2.4.2 springFrameworkVersion=6.0.8 micrometerVersion=1.10.6 openSamlVersion=4.1.1 -version=6.0.3-SNAPSHOT +version=6.0.3 kotlinVersion=1.7.22 samplesBranch=main org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError From 4f02770aaa033b6119d5050152642352f10269dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Apr 2023 16:17:33 +0000 Subject: [PATCH 2/3] Next development version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e4662024623..5df64126829 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ springBootVersion=2.4.2 springFrameworkVersion=6.0.8 micrometerVersion=1.10.6 openSamlVersion=4.1.1 -version=6.0.3 +version=6.0.4-SNAPSHOT kotlinVersion=1.7.22 samplesBranch=main org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError From c3479ddb4521b0f2569c9b9276eb7e7310acb999 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Mon, 17 Apr 2023 17:06:06 -0600 Subject: [PATCH 3/3] Pick Up SecurityContextRepository Closes gh-13008 --- .../web/configurers/X509Configurer.java | 10 ++++- .../web/configurers/X509ConfigurerTests.java | 39 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/X509Configurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/X509Configurer.java index 267eaff74e8..f545b081264 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/X509Configurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/X509Configurer.java @@ -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"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ import org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor; import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter; import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor; +import org.springframework.security.web.context.SecurityContextRepository; /** * Adds X509 based pre authentication to an application. Since validating the certificate @@ -192,6 +193,13 @@ private X509AuthenticationFilter getFilter(AuthenticationManager authenticationM if (this.authenticationDetailsSource != null) { this.x509AuthenticationFilter.setAuthenticationDetailsSource(this.authenticationDetailsSource); } + SecurityContextConfigurer securityContextConfigurer = http + .getConfigurer(SecurityContextConfigurer.class); + if (securityContextConfigurer != null && securityContextConfigurer.isRequireExplicitSave()) { + SecurityContextRepository securityContextRepository = securityContextConfigurer + .getSecurityContextRepository(); + this.x509AuthenticationFilter.setSecurityContextRepository(securityContextRepository); + } this.x509AuthenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy()); this.x509AuthenticationFilter = postProcess(this.x509AuthenticationFilter); } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java index 017e64bcabe..b67ea3da984 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/X509ConfigurerTests.java @@ -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"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.test.SpringTestContext; import org.springframework.security.config.test.SpringTestContextExtension; import org.springframework.security.core.context.SecurityContextChangedListener; @@ -45,6 +46,7 @@ import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter; import org.springframework.test.web.servlet.MockMvc; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; @@ -141,6 +143,18 @@ public void x509WhenUserDetailsServiceAndBeanConfiguredThenDoesNotUseBean() thro // @formatter:on } + // gh-13008 + @Test + public void x509WhenStatelessSessionManagementThenDoesNotCreateSession() throws Exception { + this.spring.register(StatelessSessionManagementConfig.class).autowire(); + X509Certificate certificate = loadCert("rodatexampledotcom.cer"); + // @formatter:off + this.mvc.perform(get("/").with(x509(certificate))) + .andExpect((result) -> assertThat(result.getRequest().getSession(false)).isNull()) + .andExpect(authenticated().withUsername("rod")); + // @formatter:on + } + private T loadCert(String location) { try (InputStream is = new ClassPathResource(location).getInputStream()) { CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); @@ -311,4 +325,27 @@ UserDetailsService userDetailsService() { } + @Configuration + @EnableWebSecurity + static class StatelessSessionManagementConfig { + + @Bean + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + // @formatter:off + http + .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .x509((x509) -> x509.subjectPrincipalRegex("CN=(.*?)@example.com(?:,|$)")); + // @formatter:on + return http.build(); + } + + @Bean + UserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder().username("rod").password("password") + .roles("USER", "ADMIN").build(); + return new InMemoryUserDetailsManager(user); + } + + } + }