diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java index 599afa3638..ea859ef8b4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java @@ -34,6 +34,10 @@ import org.springframework.core.annotation.Order; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.DelegatingSecurityContextRepository; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.util.ClassUtils; /** @@ -67,6 +71,8 @@ public class ManagementWebSecurityAutoConfiguration { } http.formLogin(Customizer.withDefaults()); http.httpBasic(Customizer.withDefaults()); + http.setSharedObject(SecurityContextRepository.class, new DelegatingSecurityContextRepository( + new RequestAttributeSecurityContextRepository(), new HttpSessionSecurityContextRepository())); return http.build(); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditAutoConfigurationTests.java index 471e2dd0bb..49ad2990a3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditAutoConfigurationTests.java @@ -32,8 +32,8 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.event.AbstractAuthorizationEvent; import org.springframework.security.authentication.event.AbstractAuthenticationEvent; +import org.springframework.security.authorization.event.AuthorizationEvent; import static org.assertj.core.api.Assertions.assertThat; @@ -149,7 +149,7 @@ class AuditAutoConfigurationTests { } @Override - public void onApplicationEvent(AbstractAuthorizationEvent event) { + public void onApplicationEvent(AuthorizationEvent event) { } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java index a48cfaf3fe..b1db7b8d97 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java @@ -45,6 +45,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.test.web.reactive.server.WebTestClient; /** @@ -177,22 +178,15 @@ abstract class AbstractEndpointRequestIntegrationTests { static class SecurityConfiguration { @Bean - @SuppressWarnings("deprecation") - org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() { - return new org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter() { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeHttpRequests((requests) -> { - requests.requestMatchers(EndpointRequest.toLinks()).permitAll(); - requests.requestMatchers(EndpointRequest.to(TestEndpoint1.class)).permitAll(); - requests.requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated(); - requests.anyRequest().hasRole("ADMIN"); - }); - http.httpBasic(); - } - - }; + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(EndpointRequest.toLinks()).permitAll(); + requests.requestMatchers(EndpointRequest.to(TestEndpoint1.class)).permitAll(); + requests.requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated(); + requests.anyRequest().hasRole("ADMIN"); + }); + http.httpBasic(); + return http.build(); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java index f647fbdf0d..bcea77524f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java @@ -172,18 +172,17 @@ class ManagementWebSecurityAutoConfigurationTests { } @Configuration(proxyBeanMethods = false) - @SuppressWarnings("deprecation") - static class CustomSecurityConfiguration - extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter { + static class CustomSecurityConfiguration { - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> { - requests.antMatchers("/foo").permitAll(); + requests.requestMatchers(new AntPathRequestMatcher("/foo")).permitAll(); requests.anyRequest().authenticated(); }); http.formLogin(Customizer.withDefaults()); http.httpBasic(); + return http.build(); } } @@ -193,8 +192,8 @@ class ManagementWebSecurityAutoConfigurationTests { @Bean SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { - return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()) - .build(); + return http.securityMatcher("/**") + .authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build(); } } @@ -205,8 +204,10 @@ class ManagementWebSecurityAutoConfigurationTests { @Bean @Order(SecurityProperties.BASIC_AUTH_ORDER - 1) SecurityFilterChain testRemoteDevToolsSecurityFilterChain(HttpSecurity http) throws Exception { - return http.requestMatcher(new AntPathRequestMatcher("/**")).authorizeHttpRequests().anyRequest() - .anonymous().and().csrf().disable().build(); + http.securityMatcher(new AntPathRequestMatcher("/**")); + http.authorizeHttpRequests().anyRequest().anonymous(); + http.csrf().disable(); + return http.build(); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java index aabccb68df..e455b23b67 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java @@ -20,7 +20,6 @@ import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.security.Principal; import java.util.Collection; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Supplier; @@ -55,9 +54,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.security.access.AccessDecisionVoter; -import org.springframework.security.access.SecurityConfig; -import org.springframework.security.access.vote.RoleVoter; +import org.springframework.security.authorization.AuthorityAuthorizationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.util.AntPathMatcher; @@ -469,7 +466,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi private static final class ReactiveSecurityContext implements SecurityContext { - private final RoleVoter roleVoter = new RoleVoter(); + private static final String ROLE_PREFIX = "ROLE_"; private final Authentication authentication; @@ -477,6 +474,10 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi this.authentication = authentication; } + private Authentication getAuthentication() { + return this.authentication; + } + @Override public Principal getPrincipal() { return this.authentication; @@ -484,11 +485,9 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi @Override public boolean isUserInRole(String role) { - if (!role.startsWith(this.roleVoter.getRolePrefix())) { - role = this.roleVoter.getRolePrefix() + role; - } - return this.roleVoter.vote(this.authentication, null, - Collections.singletonList(new SecurityConfig(role))) == AccessDecisionVoter.ACCESS_GRANTED; + String authority = (!role.startsWith(ROLE_PREFIX)) ? ROLE_PREFIX + role : role; + return AuthorityAuthorizationManager.hasAuthority(authority).check(this::getAuthentication, null) + .isGranted(); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AbstractAuthorizationAuditListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AbstractAuthorizationAuditListener.java index 5ca0d852d4..347b1cf4a9 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AbstractAuthorizationAuditListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AbstractAuthorizationAuditListener.java @@ -21,18 +21,21 @@ import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationListener; -import org.springframework.security.access.event.AbstractAuthorizationEvent; +import org.springframework.security.authorization.event.AuthorizationDeniedEvent; +import org.springframework.security.authorization.event.AuthorizationEvent; +import org.springframework.security.authorization.event.AuthorizationGrantedEvent; /** * Abstract {@link ApplicationListener} to expose Spring Security - * {@link AbstractAuthorizationEvent authorization events} as {@link AuditEvent}s. + * {@link AuthorizationDeniedEvent authorization denied} and + * {@link AuthorizationGrantedEvent authorization granted} events as {@link AuditEvent}s. * * @author Dave Syer * @author Vedran Pavic * @since 1.3.0 */ public abstract class AbstractAuthorizationAuditListener - implements ApplicationListener, ApplicationEventPublisherAware { + implements ApplicationListener, ApplicationEventPublisherAware { private ApplicationEventPublisher publisher; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java index fed98e54f8..586f725d6f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java @@ -17,6 +17,7 @@ package org.springframework.boot.actuate.security; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.actuate.audit.AuditEvent; @@ -75,7 +76,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList } private void onAuthenticationFailureEvent(AbstractAuthenticationFailureEvent event) { - Map data = new HashMap<>(); + Map data = new LinkedHashMap<>(); data.put("type", event.getException().getClass().getName()); data.put("message", event.getException().getMessage()); if (event.getAuthentication().getDetails() != null) { @@ -85,7 +86,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList } private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) { - Map data = new HashMap<>(); + Map data = new LinkedHashMap<>(); if (event.getAuthentication().getDetails() != null) { data.put("details", event.getAuthentication().getDetails()); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java index f151a4e52a..587c77c94f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java @@ -16,13 +16,14 @@ package org.springframework.boot.actuate.security; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.function.Supplier; import org.springframework.boot.actuate.audit.AuditEvent; -import org.springframework.security.access.event.AbstractAuthorizationEvent; -import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent; -import org.springframework.security.access.event.AuthorizationFailureEvent; +import org.springframework.security.authorization.event.AuthorizationDeniedEvent; +import org.springframework.security.authorization.event.AuthorizationEvent; +import org.springframework.security.core.Authentication; /** * Default implementation of {@link AbstractAuthorizationAuditListener}. @@ -39,30 +40,38 @@ public class AuthorizationAuditListener extends AbstractAuthorizationAuditListen public static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE"; @Override - public void onApplicationEvent(AbstractAuthorizationEvent event) { - if (event instanceof AuthenticationCredentialsNotFoundEvent credentialsNotFoundEvent) { - onAuthenticationCredentialsNotFoundEvent(credentialsNotFoundEvent); - } - else if (event instanceof AuthorizationFailureEvent authorizationFailureEvent) { - onAuthorizationFailureEvent(authorizationFailureEvent); + public void onApplicationEvent(AuthorizationEvent event) { + if (event instanceof AuthorizationDeniedEvent authorizationDeniedEvent) { + onAuthorizationDeniedEvent(authorizationDeniedEvent); } } - private void onAuthenticationCredentialsNotFoundEvent(AuthenticationCredentialsNotFoundEvent event) { - Map data = new HashMap<>(); - data.put("type", event.getCredentialsNotFoundException().getClass().getName()); - data.put("message", event.getCredentialsNotFoundException().getMessage()); - publish(new AuditEvent("", AuthenticationAuditListener.AUTHENTICATION_FAILURE, data)); + private void onAuthorizationDeniedEvent(AuthorizationDeniedEvent event) { + String name = getName(event.getAuthentication()); + Map data = new LinkedHashMap<>(); + Object details = getDetails(event.getAuthentication()); + if (details != null) { + data.put("details", details); + } + publish(new AuditEvent(name, AUTHORIZATION_FAILURE, data)); } - private void onAuthorizationFailureEvent(AuthorizationFailureEvent event) { - Map data = new HashMap<>(); - data.put("type", event.getAccessDeniedException().getClass().getName()); - data.put("message", event.getAccessDeniedException().getMessage()); - if (event.getAuthentication().getDetails() != null) { - data.put("details", event.getAuthentication().getDetails()); + private String getName(Supplier authentication) { + try { + return authentication.get().getName(); + } + catch (Exception ex) { + return ""; + } + } + + private Object getDetails(Supplier authentication) { + try { + return authentication.get().getDetails(); + } + catch (Exception ex) { + return null; } - publish(new AuditEvent(event.getAuthentication().getName(), AUTHORIZATION_FAILURE, data)); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java index cbda5c70b1..ca66cb891f 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java @@ -16,21 +16,17 @@ package org.springframework.boot.actuate.security; -import java.util.Collections; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.SecurityConfig; -import org.springframework.security.access.event.AbstractAuthorizationEvent; -import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent; -import org.springframework.security.access.event.AuthorizationFailureEvent; -import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.event.AuthorizationDeniedEvent; +import org.springframework.security.authorization.event.AuthorizationEvent; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.then; @@ -51,35 +47,48 @@ class AuthorizationAuditListenerTests { } @Test - void testAuthenticationCredentialsNotFound() { - AuditApplicationEvent event = handleAuthorizationEvent( - new AuthenticationCredentialsNotFoundEvent(this, Collections.singletonList(new SecurityConfig("USER")), - new AuthenticationCredentialsNotFoundException("Bad user"))); - assertThat(event.getAuditEvent().getType()).isEqualTo(AuthenticationAuditListener.AUTHENTICATION_FAILURE); - } - - @Test - void testAuthorizationFailure() { - AuditApplicationEvent event = handleAuthorizationEvent(new AuthorizationFailureEvent(this, - Collections.singletonList(new SecurityConfig("USER")), - new UsernamePasswordAuthenticationToken("user", "password"), new AccessDeniedException("Bad user"))); - assertThat(event.getAuditEvent().getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE); - } - - @Test - void testDetailsAreIncludedInAuditEvent() { - Object details = new Object(); - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("user", + void authorizationDeniedEvent() { + AuthorizationDecision decision = new AuthorizationDecision(false); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("spring", "password"); - authentication.setDetails(details); - AuditApplicationEvent event = handleAuthorizationEvent( - new AuthorizationFailureEvent(this, Collections.singletonList(new SecurityConfig("USER")), - authentication, new AccessDeniedException("Bad user"))); - assertThat(event.getAuditEvent().getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE); - assertThat(event.getAuditEvent().getData()).containsEntry("details", details); + authentication.setDetails("details"); + AuthorizationDeniedEvent authorizationEvent = new AuthorizationDeniedEvent<>(() -> authentication, "", + decision); + AuditEvent auditEvent = handleAuthorizationEvent(authorizationEvent).getAuditEvent(); + assertThat(auditEvent.getPrincipal()).isEqualTo("spring"); + assertThat(auditEvent.getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE); + assertThat(auditEvent.getData()).containsEntry("details", "details"); } - private AuditApplicationEvent handleAuthorizationEvent(AbstractAuthorizationEvent event) { + @Test + void authorizationDeniedEventWhenAuthenticationIsNotAvailable() { + AuthorizationDecision decision = new AuthorizationDecision(false); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("spring", + "password"); + authentication.setDetails("details"); + AuthorizationDeniedEvent authorizationEvent = new AuthorizationDeniedEvent<>(() -> { + throw new RuntimeException("No authentication"); + }, "", decision); + AuditEvent auditEvent = handleAuthorizationEvent(authorizationEvent).getAuditEvent(); + assertThat(auditEvent.getPrincipal()).isEqualTo(""); + assertThat(auditEvent.getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE); + assertThat(auditEvent.getData()).doesNotContainKey("details"); + } + + @Test + void authorizationDeniedEventWhenAuthenticationDoesNotHaveDetails() { + AuthorizationDecision decision = new AuthorizationDecision(false); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("spring", + "password"); + AuthorizationDeniedEvent authorizationEvent = new AuthorizationDeniedEvent<>(() -> authentication, "", + decision); + AuditEvent auditEvent = handleAuthorizationEvent(authorizationEvent).getAuditEvent(); + assertThat(auditEvent.getPrincipal()).isEqualTo("spring"); + assertThat(auditEvent.getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE); + assertThat(auditEvent.getData()).doesNotContainKey("details"); + } + + private AuditApplicationEvent handleAuthorizationEvent(AuthorizationEvent event) { ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(AuditApplicationEvent.class); this.listener.onApplicationEvent(event); then(this.publisher).should().publishEvent(eventCaptor.capture()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java index 1317f19cf9..fc4f2d450b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java @@ -40,10 +40,7 @@ class DefaultWebSecurityCondition extends AllNestedConditions { } - @ConditionalOnMissingBean({ - org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class, - SecurityFilterChain.class }) - @SuppressWarnings("deprecation") + @ConditionalOnMissingBean({ SecurityFilterChain.class }) static class Beans { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java index 2911e9afd5..7c59434041 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java index f4ad7824a4..0ba8029038 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java @@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Import; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; /** * {@link EnableAutoConfiguration Auto-configuration} for OAuth2 resource server support. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java index 2363eca9fd..e83addd521 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java @@ -29,6 +29,10 @@ import org.springframework.security.config.BeanIds; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.DelegatingSecurityContextRepository; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; /** * {@link Configuration @Configuration} class securing servlet applications. @@ -57,6 +61,8 @@ class SpringBootWebSecurityConfiguration { http.authorizeHttpRequests().anyRequest().authenticated(); http.formLogin(); http.httpBasic(); + http.setSharedObject(SecurityContextRepository.class, new DelegatingSecurityContextRepository( + new RequestAttributeSecurityContextRepository(), new HttpSessionSecurityContextRepository())); return http.build(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java index 10f146e9a4..e88643a038 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java @@ -30,7 +30,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Lazy; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.authentication.AuthenticationProvider; @@ -72,7 +71,6 @@ public class UserDetailsServiceAutoConfiguration { private static final Log logger = LogFactory.getLog(UserDetailsServiceAutoConfiguration.class); @Bean - @Lazy public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties, ObjectProvider passwordEncoder) { SecurityProperties.User user = properties.getUser(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/aop/AopAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/aop/AopAutoConfigurationTests.java index 18b69aa51f..b2982a94c0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/aop/AopAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/aop/AopAutoConfigurationTests.java @@ -32,7 +32,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.web.bind.annotation.RequestMapping; import static org.assertj.core.api.Assertions.assertThat; @@ -166,7 +166,7 @@ class AopAutoConfigurationTests { } - @EnableGlobalMethodSecurity(prePostEnabled = true) + @EnableMethodSecurity(prePostEnabled = true) @Configuration(proxyBeanMethods = false) static class EnableGlobalMethodSecurityConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java index b5339283de..816909f2f4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java @@ -38,7 +38,7 @@ import org.springframework.graphql.execution.SecurityDataFetcherExceptionResolve import org.springframework.http.MediaType; import org.springframework.lang.Nullable; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; @@ -151,7 +151,7 @@ class GraphQlWebMvcSecurityAutoConfigurationTests { @Configuration(proxyBeanMethods = false) @EnableWebSecurity - @EnableGlobalMethodSecurity(prePostEnabled = true) + @EnableMethodSecurity(prePostEnabled = true) @SuppressWarnings("deprecation") static class SecurityConfig { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2WebSecurityConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2WebSecurityConfigurationTests.java index 1d7c3a11e6..7597f09d70 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2WebSecurityConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2WebSecurityConfigurationTests.java @@ -22,9 +22,11 @@ import java.util.List; import jakarta.servlet.Filter; import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -56,7 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ class OAuth2WebSecurityConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(); @Test void securityConfigurerConfiguresOAuth2Login() { @@ -113,21 +115,10 @@ class OAuth2WebSecurityConfigurationTests { .run((context) -> assertThat(context).hasSingleBean(OAuth2AuthorizedClientRepository.class)); } - @Test - void securityFilterChainConfigBacksOffWhenOtherWebSecurityAdapterPresent() { - this.contextRunner - .withUserConfiguration(TestWebSecurityConfigurerConfig.class, OAuth2WebSecurityConfiguration.class) - .run((context) -> { - assertThat(getFilters(context, OAuth2LoginAuthenticationFilter.class)).isEmpty(); - assertThat(getFilters(context, OAuth2AuthorizationCodeGrantFilter.class)).isEmpty(); - assertThat(context).getBean(OAuth2AuthorizedClientService.class).isNotNull(); - }); - } - @Test void securityFilterChainConfigBacksOffWhenOtherSecurityFilterChainBeanPresent() { - this.contextRunner - .withUserConfiguration(TestSecurityFilterChainConfig.class, OAuth2WebSecurityConfiguration.class) + this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class)) + .withUserConfiguration(TestSecurityFilterChainConfiguration.class, OAuth2WebSecurityConfiguration.class) .run((context) -> { assertThat(getFilters(context, OAuth2LoginAuthenticationFilter.class)).isEmpty(); assertThat(getFilters(context, OAuth2AuthorizationCodeGrantFilter.class)).isEmpty(); @@ -164,7 +155,7 @@ class OAuth2WebSecurityConfigurationTests { }); } - private List getFilters(AssertableApplicationContext context, Class filter) { + private List getFilters(AssertableWebApplicationContext context, Class filter) { FilterChainProxy filterChain = (FilterChainProxy) context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN); List filterChains = filterChain.getFilterChains(); List filters = filterChains.get(0).getFilters(); @@ -228,20 +219,12 @@ class OAuth2WebSecurityConfigurationTests { @Configuration(proxyBeanMethods = false) @Import(ClientRegistrationRepositoryConfiguration.class) - @SuppressWarnings("deprecation") - static class TestWebSecurityConfigurerConfig - extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter { - - } - - @Configuration(proxyBeanMethods = false) - @Import(ClientRegistrationRepositoryConfiguration.class) - static class TestSecurityFilterChainConfig { + static class TestSecurityFilterChainConfiguration { @Bean SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { - return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()) - .build(); + return http.securityMatcher("/**") + .authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java index daeb054c59..b53fa9340b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java @@ -60,7 +60,7 @@ import org.springframework.security.oauth2.jwt.JwtTimestampValidator; import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.SupplierReactiveJwtDecoder; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager; import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenReactiveAuthenticationManager; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java index a6541cfd27..16ca830f8a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java @@ -37,6 +37,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; @@ -57,10 +58,10 @@ import org.springframework.security.oauth2.jwt.JwtIssuerValidator; import org.springframework.security.oauth2.jwt.JwtTimestampValidator; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.SupplierJwtDecoder; -import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; -import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter; +import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter; import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.test.util.ReflectionTestUtils; @@ -579,7 +580,7 @@ class OAuth2ResourceServerAutoConfigurationTests { @Test void jwtSecurityConfigurerBacksOffWhenSecurityFilterChainBeanIsPresent() { - this.contextRunner + this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class)) .withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com") .withUserConfiguration(JwtDecoderConfig.class, TestSecurityFilterChainConfig.class) .run((context) -> assertThat(context).hasSingleBean(SecurityFilterChain.class)); @@ -587,7 +588,8 @@ class OAuth2ResourceServerAutoConfigurationTests { @Test void opaqueTokenSecurityConfigurerBacksOffWhenSecurityFilterChainBeanIsPresent() { - this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class) + this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class)) + .withUserConfiguration(TestSecurityFilterChainConfig.class) .withPropertyValues( "spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com", "spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id", @@ -692,8 +694,9 @@ class OAuth2ResourceServerAutoConfigurationTests { @Bean SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { - return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()) - .build(); + http.securityMatcher("/**"); + http.authorizeHttpRequests().anyRequest().authenticated(); + return http.build(); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java index b9e52163ee..c83d1a7813 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -41,7 +42,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; -import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter; +import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter; import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutRequestFilter; import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; @@ -205,17 +206,10 @@ class Saml2RelyingPartyAutoConfigurationTests { .run((context) -> assertThat(hasFilter(context, Saml2WebSsoAuthenticationFilter.class)).isTrue()); } - @Test - void samlLoginShouldBackOffWhenAWebSecurityConfigurerAdapterIsDefined() { - this.contextRunner.withUserConfiguration(WebSecurityConfigurerAdapterConfiguration.class) - .withPropertyValues(getPropertyValues()) - .run((context) -> assertThat(hasFilter(context, Saml2WebSsoAuthenticationFilter.class)).isFalse()); - } - @Test void samlLoginShouldBackOffWhenASecurityFilterChainBeanIsPresent() { - this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class) - .withPropertyValues(getPropertyValues()) + this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class)) + .withUserConfiguration(TestSecurityFilterChainConfig.class).withPropertyValues(getPropertyValues()) .run((context) -> assertThat(hasFilter(context, Saml2WebSsoAuthenticationFilter.class)).isFalse()); } @@ -303,26 +297,13 @@ class Saml2RelyingPartyAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - static class WebSecurityConfigurerAdapterConfiguration { - - @Bean - @SuppressWarnings("deprecation") - org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() { - return new org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter() { - - }; - } - - } - @Configuration(proxyBeanMethods = false) static class TestSecurityFilterChainConfig { @Bean SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { - return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()) - .build(); + return http.securityMatcher("/**") + .authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build(); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java index 9327e980d9..1c5b4b1d6b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java @@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.test.City; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -45,7 +46,6 @@ import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension; @@ -89,30 +89,11 @@ class SecurityAutoConfigurationTests { @Test void securityConfigurerBacksOffWhenOtherSecurityFilterChainBeanPresent() { - this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class).run((context) -> { - assertThat(context.getBeansOfType(SecurityFilterChain.class).size()).isEqualTo(1); - assertThat(context.containsBean("testSecurityFilterChain")).isTrue(); - }); - } - - @Test - @SuppressWarnings("deprecation") - void securityConfigurerBacksOffWhenOtherWebSecurityAdapterBeanPresent() { - this.contextRunner.withUserConfiguration(WebSecurity.class).run((context) -> { - assertThat(context.getBeansOfType( - org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class) - .size()).isEqualTo(1); - assertThat(context.containsBean("securityAutoConfigurationTests.WebSecurity")).isTrue(); - }); - } - - @Test - void testDefaultFilterOrderWithSecurityAdapter() { - this.contextRunner - .withConfiguration(AutoConfigurations.of(WebSecurity.class, SecurityFilterAutoConfiguration.class)) - .run((context) -> assertThat( - context.getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class) - .getOrder()).isEqualTo(OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100)); + this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class)) + .withUserConfiguration(TestSecurityFilterChainConfig.class).run((context) -> { + assertThat(context.getBeansOfType(SecurityFilterChain.class).size()).isEqualTo(1); + assertThat(context.containsBean("testSecurityFilterChain")).isTrue(); + }); } @Test @@ -255,21 +236,13 @@ class SecurityAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - @EnableWebSecurity - @SuppressWarnings("deprecation") - static class WebSecurity - extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter { - - } - @Configuration(proxyBeanMethods = false) static class TestSecurityFilterChainConfig { @Bean SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception { - return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()) - .build(); + return http.securityMatcher("/**") + .authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build(); } @@ -281,7 +254,7 @@ class SecurityAutoConfigurationTests { @Bean @ConfigurationPropertiesBinding Converter targetTypeConverter() { - return new Converter() { + return new Converter<>() { @Override public TargetType convert(String input) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java index 73f2bd39df..53d214e320 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java @@ -22,7 +22,6 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfigurationTests.WebSecurity; import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ConverterBean; import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.DeserializerBean; import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ExampleController; @@ -53,7 +52,7 @@ class SecurityFilterAutoConfigurationTests { @Configuration(proxyBeanMethods = false) @Import({ DeserializerBean.class, JacksonModuleBean.class, ExampleController.class, ConverterBean.class }) @ImportAutoConfiguration({ WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebSecurity.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, SecurityFilterAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) static class Config { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java index 9fa64ddd8a..b65d3bdd1d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java @@ -36,7 +36,6 @@ import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.TestingAuthenticationProvider; import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; @@ -164,12 +163,6 @@ class UserDetailsServiceAutoConfigurationTests { .run(((context) -> assertThat(context).doesNotHaveBean(InMemoryUserDetailsManager.class))); } - @Test - void generatedPasswordShouldNotBePrintedIfAuthenticationManagerBuilderIsUsed(CapturedOutput output) { - this.contextRunner.withUserConfiguration(TestConfigWithAuthenticationManagerBuilder.class) - .run(((context) -> assertThat(output).doesNotContain("Using generated security password: "))); - } - private void testPasswordEncoding(Class configClass, String providedPassword, String expectedPassword) { this.contextRunner.withUserConfiguration(configClass) .withPropertyValues("spring.security.user.password=" + providedPassword).run(((context) -> { @@ -264,24 +257,6 @@ class UserDetailsServiceAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - @Import(TestSecurityConfiguration.class) - static class TestConfigWithAuthenticationManagerBuilder { - - @Bean - @SuppressWarnings("deprecation") - org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() { - return new org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter() { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("hero").password("{noop}hero").roles("HERO", "USER").and() - .withUser("user").password("{noop}user").roles("USER"); - } - }; - } - - } - @Configuration(proxyBeanMethods = false) static class TestAuthenticationManagerResolverConfiguration { diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 802768486c..218a5d1bb8 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1497,7 +1497,7 @@ bom { ] } } - library("Spring Security", "6.0.0-M7") { + library("Spring Security", "6.0.0-SNAPSHOT") { group("org.springframework.security") { imports = [ "spring-security-bom" diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java index 67d55b4113..577103b523 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java @@ -17,7 +17,6 @@ package org.springframework.boot.devtools.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.context.annotation.Bean; @@ -47,11 +46,10 @@ class RemoteDevtoolsSecurityConfiguration { @Bean @Order(SecurityProperties.BASIC_AUTH_ORDER - 1) - @ConditionalOnMissingBean(org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class) - @SuppressWarnings("deprecation") SecurityFilterChain devtoolsSecurityFilterChain(HttpSecurity http) throws Exception { - http.requestMatcher(new AntPathRequestMatcher(this.url)).authorizeHttpRequests().anyRequest().anonymous().and() - .csrf().disable(); + http.securityMatcher(new AntPathRequestMatcher(this.url)); + http.authorizeHttpRequests().anyRequest().anonymous(); + http.csrf().disable(); return http.build(); } diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java index 230be0fdd1..3acc3e9193 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java @@ -44,7 +44,6 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletContext; import org.springframework.security.config.BeanIds; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -183,25 +182,6 @@ class RemoteDevToolsAutoConfigurationTests { mockMvc.perform(MockMvcRequestBuilders.get("/my-path")).andExpect(status().isUnauthorized()); } - @Test - void securityConfigurationWhenWebSecurityConfigurerAdapterIsFound2() throws Exception { - this.context = getContext(() -> { - AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext(); - context.setServletContext(new MockServletContext()); - context.register(Config.class, PropertyPlaceholderAutoConfiguration.class, - TestWebSecurityConfigurerAdapter.class); - TestPropertyValues.of("spring.devtools.remote.secret:supersecret").applyTo(context); - context.refresh(); - return context; - }); - DispatcherFilter filter = this.context.getBean(DispatcherFilter.class); - MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(springSecurity()).addFilter(filter) - .build(); - mockMvc.perform(MockMvcRequestBuilders.get(DEFAULT_CONTEXT_PATH + "/restart").header(DEFAULT_SECRET_HEADER_NAME, - "supersecret")).andExpect(status().isOk()); - assertRestartInvoked(true); - } - @Test void disableRestart() throws Exception { this.context = getContext(() -> loadContext("spring.devtools.remote.secret:supersecret", @@ -270,18 +250,6 @@ class RemoteDevToolsAutoConfigurationTests { } - @Configuration(proxyBeanMethods = false) - @SuppressWarnings("deprecation") - static class TestWebSecurityConfigurerAdapter - extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/foo/**").authorizeHttpRequests().anyRequest().authenticated().and().httpBasic(); - } - - } - /** * Mock {@link HttpRestartServer} implementation. */ diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc index 72d14cc1ea..4f4fea8376 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/endpoints.adoc @@ -212,8 +212,8 @@ You can use the configprop:management.endpoints.web.exposure.include[] property NOTE: Before setting the `management.endpoints.web.exposure.include`, ensure that the exposed actuators do not contain sensitive information, are secured by placing them behind a firewall, or are secured by something like Spring Security. -If Spring Security is on the classpath and no other `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean is present, all actuators other than `/health` are secured by Spring Boot auto-configuration. -If you define a custom `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean, Spring Boot auto-configuration backs off and lets you fully control the actuator access rules. +If Spring Security is on the classpath and no other `SecurityFilterChain` bean is present, all actuators other than `/health` are secured by Spring Boot auto-configuration. +If you define a custom `SecurityFilterChain` bean, Spring Boot auto-configuration backs off and lets you fully control the actuator access rules. If you wish to configure custom security for HTTP endpoints (for example, to allow only users with a certain role to access them), Spring Boot provides some convenient `RequestMatcher` objects that you can use in combination with Spring Security. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/security.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/security.adoc index d143ddad44..9f7509e035 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/security.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/security.adoc @@ -8,7 +8,7 @@ For more about Spring Security, see the {spring-security}[Spring Security projec [[howto.security.switch-off-spring-boot-configuration]] === Switch off the Spring Boot Security Configuration -If you define a `@Configuration` with a `WebSecurityConfigurerAdapter` or a `SecurityFilterChain` bean in your application, it switches off the default webapp security settings in Spring Boot. +If you define a `@Configuration` with a `SecurityFilterChain` bean in your application, it switches off the default webapp security settings in Spring Boot. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc index bd0d68d792..79a724590a 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc @@ -38,7 +38,7 @@ To switch off the default web application security configuration completely or t To also switch off the `UserDetailsService` configuration, you can add a bean of type `UserDetailsService`, `AuthenticationProvider`, or `AuthenticationManager`. -Access rules can be overridden by adding a custom `SecurityFilterChain` or `WebSecurityConfigurerAdapter` bean. +Access rules can be overridden by adding a custom `SecurityFilterChain` bean. Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. `EndpointRequest` can be used to create a `RequestMatcher` that is based on the configprop:management.endpoints.web.base-path[] property. `PathRequest` can be used to create a `RequestMatcher` for resources in commonly used locations. diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java index e42829a383..b65ccea693 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java @@ -27,7 +27,7 @@ public class MySecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()); + http.securityMatcher(EndpointRequest.toAnyEndpoint()); http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll()); return http.build(); } diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java index 336edfcd52..409cbf6ee4 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java @@ -29,7 +29,7 @@ public class MySecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http.requestMatcher(EndpointRequest.toAnyEndpoint()); + http.securityMatcher(EndpointRequest.toAnyEndpoint()); http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN")); http.httpBasic(withDefaults()); return http.build(); diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java index 6c534725b0..6f7926175d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java @@ -33,7 +33,7 @@ public class DevProfileSecurityConfiguration { @Bean @Order(Ordered.HIGHEST_PRECEDENCE) SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throws Exception { - http.requestMatcher(PathRequest.toH2Console()); + http.securityMatcher(PathRequest.toH2Console()); http.authorizeHttpRequests(yourCustomAuthorization()); http.csrf((csrf) -> csrf.disable()); http.headers((headers) -> headers.frameOptions().sameOrigin()); diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt index 0debabed19..26afa1a1b2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt @@ -27,7 +27,7 @@ class MySecurityConfiguration { @Bean fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { + http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests -> requests.anyRequest().permitAll() } return http.build() } diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt index 0b74bd62be..4719b42843 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt @@ -27,7 +27,7 @@ class MySecurityConfiguration { @Bean fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests -> + http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests -> requests.anyRequest().hasRole("ENDPOINT_ADMIN") } http.httpBasic() diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java index 2c1599ccf5..764d9dfba7 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java @@ -60,7 +60,6 @@ class WebMvcTypeExcludeFilterTests { assertThat(excludes(filter, ExampleMessageConverter.class)).isFalse(); assertThat(excludes(filter, ExampleService.class)).isTrue(); assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isFalse(); assertThat(excludes(filter, SecurityFilterChain.class)).isFalse(); assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isFalse(); assertThat(excludes(filter, ExampleModule.class)).isFalse(); @@ -78,7 +77,6 @@ class WebMvcTypeExcludeFilterTests { assertThat(excludes(filter, ExampleMessageConverter.class)).isFalse(); assertThat(excludes(filter, ExampleService.class)).isTrue(); assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isFalse(); assertThat(excludes(filter, SecurityFilterChain.class)).isFalse(); assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isFalse(); assertThat(excludes(filter, ExampleModule.class)).isFalse(); @@ -96,7 +94,6 @@ class WebMvcTypeExcludeFilterTests { assertThat(excludes(filter, ExampleMessageConverter.class)).isTrue(); assertThat(excludes(filter, ExampleService.class)).isTrue(); assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isTrue(); assertThat(excludes(filter, SecurityFilterChain.class)).isTrue(); assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isTrue(); assertThat(excludes(filter, ExampleModule.class)).isTrue(); @@ -130,7 +127,6 @@ class WebMvcTypeExcludeFilterTests { assertThat(excludes(filter, ExampleMessageConverter.class)).isFalse(); assertThat(excludes(filter, ExampleService.class)).isTrue(); assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isFalse(); assertThat(excludes(filter, SecurityFilterChain.class)).isFalse(); assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isFalse(); assertThat(excludes(filter, ExampleModule.class)).isFalse(); @@ -204,12 +200,6 @@ class WebMvcTypeExcludeFilterTests { } - @SuppressWarnings("deprecation") - static class ExampleWebSecurityConfigurer - extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter { - - } - static class ExampleHandlerInterceptor implements HandlerInterceptor { } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommand.java b/spring-boot-project/spring-boot-tools/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommand.java index 6217133d26..9c652e0002 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommand.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommand.java @@ -54,7 +54,7 @@ public class EncodePasswordCommand extends OptionParsingCommand { Map> encoders = new LinkedHashMap<>(); encoders.put("default", PasswordEncoderFactories::createDelegatingPasswordEncoder); encoders.put("bcrypt", BCryptPasswordEncoder::new); - encoders.put("pbkdf2", Pbkdf2PasswordEncoder::new); + encoders.put("pbkdf2", Pbkdf2PasswordEncoder::defaultsForSpringSecurity_v5_8); ENCODERS = Collections.unmodifiableMap(encoders); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommandTests.java b/spring-boot-project/spring-boot-tools/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommandTests.java index 2980ae3b08..37f12c4243 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommandTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/encodepassword/EncodePasswordCommandTests.java @@ -83,7 +83,8 @@ class EncodePasswordCommandTests { ExitStatus status = command.run("-a", "pbkdf2", "boot"); then(this.log).should().info(this.message.capture()); assertThat(this.message.getValue()).doesNotStartWith("{"); - assertThat(new Pbkdf2PasswordEncoder().matches("boot", this.message.getValue())).isTrue(); + assertThat(Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8().matches("boot", this.message.getValue())) + .isTrue(); assertThat(status).isEqualTo(ExitStatus.OK); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java index abec29aa50..ab476cf12e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java @@ -56,14 +56,14 @@ public class SecurityConfiguration { @Bean SecurityFilterChain configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> { - requests.mvcMatchers("/actuator/beans").hasRole("BEANS"); + requests.requestMatchers("/actuator/beans").hasRole("BEANS"); requests.requestMatchers(EndpointRequest.to("health")).permitAll(); requests.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)) .hasRole("ACTUATOR"); requests.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll(); - requests.antMatchers("/foo").permitAll(); - requests.antMatchers("/error").permitAll(); - requests.antMatchers("/**").hasRole("USER"); + requests.requestMatchers("/foo").permitAll(); + requests.requestMatchers("/error").permitAll(); + requests.requestMatchers("/**").hasRole("USER"); }); http.cors(Customizer.withDefaults()); http.httpBasic(); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java index c1798d51c7..68114a4f71 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java @@ -128,7 +128,8 @@ abstract class AbstractSampleActuatorCustomSecurityTests { @Test void secureServletEndpointWithAnonymous() { - ResponseEntity entity = restTemplate().getForEntity("/actuator/se1", String.class); + ResponseEntity entity = restTemplate().getForEntity(getManagementPath() + "/actuator/se1", + String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); entity = restTemplate().getForEntity(getManagementPath() + "/actuator/se1/list", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java index 8375ae5d55..362ebc6ef2 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java @@ -18,7 +18,7 @@ package smoketest.graphql; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; @@ -30,7 +30,7 @@ import static org.springframework.security.config.Customizer.withDefaults; @Configuration(proxyBeanMethods = false) @EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) +@EnableMethodSecurity(prePostEnabled = true) public class SecurityConfig { @Bean diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java index 0a9c2282d8..1612b9d294 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java @@ -40,15 +40,14 @@ public class SecurityConfiguration { @Bean SecurityFilterChain configure(HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeHttpRequests() - .requestMatchers(EndpointRequest.to("health")).permitAll() - .requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)).hasRole("ACTUATOR") - .antMatchers("/**").hasRole("USER") - .and() - .httpBasic(); + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(EndpointRequest.to("health")).permitAll(); + requests.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)) + .hasRole("ACTUATOR"); + requests.requestMatchers("/**").hasRole("USER"); + }); + http.httpBasic(); return http.build(); - // @formatter:on } } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/main/java/smoketest/secure/SampleSecureApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/main/java/smoketest/secure/SampleSecureApplication.java index 5927065c76..152b1c6664 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/main/java/smoketest/secure/SampleSecureApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/main/java/smoketest/secure/SampleSecureApplication.java @@ -22,13 +22,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.context.SecurityContextHolder; @EnableAutoConfiguration @ComponentScan -@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) +@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) public class SampleSecureApplication implements CommandLineRunner { @Autowired diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/test/java/smoketest/secure/SampleSecureApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/test/java/smoketest/secure/SampleSecureApplicationTests.java index 4a63b387e9..a744da876a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/test/java/smoketest/secure/SampleSecureApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure/src/test/java/smoketest/secure/SampleSecureApplicationTests.java @@ -26,6 +26,7 @@ import org.springframework.security.access.AccessDeniedException; 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.SecurityContextHolder; import static org.assertj.core.api.Assertions.assertThat; @@ -62,7 +63,8 @@ class SampleSecureApplicationTests { @Test void authenticated() { - SecurityContextHolder.getContext().setAuthentication(this.authentication); + SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("user", "N/A", + AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"))); assertThat("Hello Security").isEqualTo(this.service.secure()); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java new file mode 100644 index 0000000000..912332b3e8 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.session.hazelcast; + +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * Security configuration. + * + * @author Madhura Bhave + */ +@Configuration(proxyBeanMethods = false) +class SecurityConfiguration { + + @Bean + SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll(); + requests.anyRequest().authenticated(); + }); + http.formLogin(Customizer.withDefaults()); + http.httpBasic(Customizer.withDefaults()); + http.csrf().disable(); + return http.build(); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java index ff84a1e680..0de305cc77 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java @@ -18,6 +18,7 @@ package smoketest.session.hazelcast; import java.net.URI; import java.util.Base64; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -27,11 +28,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import static org.assertj.core.api.Assertions.assertThat; @@ -50,10 +55,7 @@ class SampleSessionHazelcastApplicationTests { @Test @SuppressWarnings("unchecked") void sessionsEndpointShouldReturnUserSession() { - URI uri = URI.create("/"); - ResponseEntity firstResponse = performRequest(uri, null); - String cookie = firstResponse.getHeaders().getFirst("Set-Cookie"); - performRequest(uri, cookie).getBody(); + performLogin(); ResponseEntity> entity = getSessions(); assertThat(entity).isNotNull(); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -61,29 +63,21 @@ class SampleSessionHazelcastApplicationTests { assertThat(sessions.size()).isEqualTo(1); } - private ResponseEntity performRequest(URI uri, String cookie) { - HttpHeaders headers = getHeaders(cookie); - RequestEntity request = new RequestEntity<>(headers, HttpMethod.GET, uri); - return this.restTemplate.exchange(request, String.class); - } - - private HttpHeaders getHeaders(String cookie) { + private String performLogin() { HttpHeaders headers = new HttpHeaders(); - if (cookie != null) { - headers.set("Cookie", cookie); - } - else { - headers.set("Authorization", getBasicAuth()); - } - return headers; - } - - private String getBasicAuth() { - return "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes()); + headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + MultiValueMap form = new LinkedMultiValueMap<>(); + form.set("username", "user"); + form.set("password", "password"); + ResponseEntity entity = this.restTemplate.exchange("/login", HttpMethod.POST, + new HttpEntity<>(form, headers), String.class); + return entity.getHeaders().getFirst("Set-Cookie"); } private ResponseEntity> getSessions() { - HttpHeaders headers = getHeaders(null); + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", getBasicAuth()); RequestEntity request = new RequestEntity<>(headers, HttpMethod.GET, URI.create("/actuator/sessions?username=user")); ParameterizedTypeReference> stringObjectMap = new ParameterizedTypeReference>() { @@ -91,4 +85,8 @@ class SampleSessionHazelcastApplicationTests { return this.restTemplate.exchange(request, stringObjectMap); } + private String getBasicAuth() { + return "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes()); + } + } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java new file mode 100644 index 0000000000..0ee5bd5b2c --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.session; + +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * Security configuration. + * + * @author Madhura Bhave + */ +@Configuration(proxyBeanMethods = false) +class SecurityConfiguration { + + @Bean + SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll(); + requests.anyRequest().authenticated(); + }); + http.formLogin(Customizer.withDefaults()); + http.httpBasic(Customizer.withDefaults()); + http.csrf().disable(); + return http.build(); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java index c989d223e5..08d5eab0ad 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java @@ -18,6 +18,7 @@ package smoketest.session; import java.net.URI; import java.util.Base64; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -27,11 +28,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import static org.assertj.core.api.Assertions.assertThat; @@ -53,9 +58,8 @@ class SampleSessionJdbcApplicationTests { @Test void sessionExpiry() throws Exception { - ResponseEntity firstResponse = performRequest(ROOT_URI, null); - String sessionId1 = firstResponse.getBody(); - String cookie = firstResponse.getHeaders().getFirst("Set-Cookie"); + String cookie = performLogin(); + String sessionId1 = performRequest(ROOT_URI, cookie).getBody(); String sessionId2 = performRequest(ROOT_URI, cookie).getBody(); assertThat(sessionId1).isEqualTo(sessionId2); Thread.sleep(2100); @@ -63,10 +67,22 @@ class SampleSessionJdbcApplicationTests { assertThat(loginPage).containsIgnoringCase("login"); } + private String performLogin() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + MultiValueMap form = new LinkedMultiValueMap<>(); + form.set("username", "user"); + form.set("password", "password"); + ResponseEntity entity = this.restTemplate.exchange("/login", HttpMethod.POST, + new HttpEntity<>(form, headers), String.class); + return entity.getHeaders().getFirst("Set-Cookie"); + } + @Test @SuppressWarnings("unchecked") void sessionsEndpointShouldReturnUserSession() { - performRequest(ROOT_URI, null); + performLogin(); ResponseEntity> response = getSessions(); assertThat(response).isNotNull(); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java new file mode 100644 index 0000000000..1177f51f13 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.session.mongodb; + +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * Security configuration. + * + * @author Madhura Bhave + */ +@Configuration(proxyBeanMethods = false) +class SecurityConfiguration { + + @Bean + SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll(); + requests.anyRequest().authenticated(); + }); + http.formLogin(Customizer.withDefaults()); + http.httpBasic(Customizer.withDefaults()); + http.csrf().disable(); + return http.build(); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/test/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/test/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java index cda1b9a7e0..997d5a9e35 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/test/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/test/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java @@ -18,6 +18,7 @@ package smoketest.session.mongodb; import java.net.URI; import java.time.Duration; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -32,13 +33,17 @@ import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import static org.assertj.core.api.Assertions.assertThat; @@ -69,7 +74,7 @@ public class SampleSessionMongoApplicationTests { @Test @SuppressWarnings("unchecked") void sessionsEndpointShouldReturnUserSessions() { - createSession(URI.create("/")); + performLogin(); ResponseEntity> response = getSessions(); assertThat(response).isNotNull(); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -86,9 +91,16 @@ public class SampleSessionMongoApplicationTests { assertThat(entity.getBody()).contains("maxWireVersion"); } - private void createSession(URI uri) { - RequestEntity request = getRequestEntity(uri); - this.restTemplate.exchange(request, String.class); + private String performLogin() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + MultiValueMap form = new LinkedMultiValueMap<>(); + form.set("username", "user"); + form.set("password", "password"); + ResponseEntity entity = this.restTemplate.exchange("/login", HttpMethod.POST, + new HttpEntity<>(form, headers), String.class); + return entity.getHeaders().getFirst("Set-Cookie"); } private RequestEntity getRequestEntity(URI uri) { diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java new file mode 100644 index 0000000000..16cd3948f4 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.session.redis; + +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * Security configuration. + * + * @author Madhura Bhave + */ +@Configuration(proxyBeanMethods = false) +class SecurityConfiguration { + + @Bean + SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll(); + requests.anyRequest().authenticated(); + }); + http.formLogin(Customizer.withDefaults()); + http.httpBasic(Customizer.withDefaults()); + http.csrf().disable(); + return http.build(); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java index 7023372543..9926e896c8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java @@ -17,6 +17,7 @@ package smoketest.session.redis; import java.net.URI; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,13 +30,17 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.testsupport.testcontainers.RedisContainer; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import static org.assertj.core.api.Assertions.assertThat; @@ -63,7 +68,7 @@ public class SampleSessionRedisApplicationTests { @Test @SuppressWarnings("unchecked") void sessionsEndpointShouldReturnUserSessions() { - createSession(URI.create("/")); + performLogin(); ResponseEntity> response = this.getSessions(); assertThat(response).isNotNull(); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -71,9 +76,16 @@ public class SampleSessionRedisApplicationTests { assertThat(sessions.size()).isEqualTo(1); } - private void createSession(URI uri) { - RequestEntity request = getRequestEntity(uri); - this.restTemplate.exchange(request, String.class); + private String performLogin() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + MultiValueMap form = new LinkedMultiValueMap<>(); + form.set("username", "user"); + form.set("password", "password"); + ResponseEntity entity = this.restTemplate.exchange("/login", HttpMethod.POST, + new HttpEntity<>(form, headers), String.class); + return entity.getHeaders().getFirst("Set-Cookie"); } private RequestEntity getRequestEntity(URI uri) { diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java index adb7d346e1..0f15ca638e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java @@ -24,18 +24,20 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.access.annotation.Secured; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @SpringBootApplication -@EnableGlobalMethodSecurity(securedEnabled = true) +@EnableMethodSecurity(securedEnabled = true) public class SampleMethodSecurityApplication implements WebMvcConfigurer { @Override @@ -69,8 +71,8 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer { @Bean SecurityFilterChain configure(HttpSecurity http) throws Exception { http.csrf().disable(); - http.authorizeHttpRequests( - (requests) -> requests.anyRequest().fullyAuthenticated().shouldFilterAllDispatcherTypes(false)); + http.authorizeHttpRequests((requests) -> requests.anyRequest().fullyAuthenticated()); + http.httpBasic(); http.formLogin((form) -> form.loginPage("/login").permitAll()); http.exceptionHandling((exceptions) -> exceptions.accessDeniedPage("/access")); return http.build(); @@ -85,10 +87,10 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer { @Bean SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception { http.csrf().disable(); - http.requestMatcher(EndpointRequest.toAnyEndpoint()); - http.authorizeHttpRequests( - (requests) -> requests.anyRequest().authenticated().shouldFilterAllDispatcherTypes(false)); + http.securityMatcher(EndpointRequest.toAnyEndpoint()); + http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated()); http.httpBasic(); + http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository()); return http.build(); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathErrorPageTests.java index 34618711f5..9906554b1e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathErrorPageTests.java @@ -21,6 +21,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; /** * Tests to ensure that the error page with a custom servlet path is accessible only to @@ -45,10 +47,11 @@ class CustomServletPathErrorPageTests extends AbstractErrorPageTests { @Bean SecurityFilterChain configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> { - requests.antMatchers("/custom/servlet/path/public/**").permitAll(); + requests.requestMatchers("/public/**").permitAll(); requests.anyRequest().fullyAuthenticated(); }); http.httpBasic(); + http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository()); http.formLogin((form) -> form.loginPage("/custom/servlet/path/login").permitAll()); return http.build(); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathUnauthenticatedErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathUnauthenticatedErrorPageTests.java index 27300394ad..ba4ce2e9af 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathUnauthenticatedErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/CustomServletPathUnauthenticatedErrorPageTests.java @@ -20,6 +20,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; /** * Tests for error page that permits access to all with a custom servlet path. @@ -44,10 +46,11 @@ class CustomServletPathUnauthenticatedErrorPageTests extends AbstractUnauthentic @Bean SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> { - requests.antMatchers("/custom/servlet/path/error").permitAll(); - requests.antMatchers("/custom/servlet/path/public/**").permitAll(); + requests.requestMatchers("/error").permitAll(); + requests.requestMatchers("/public/**").permitAll(); requests.anyRequest().authenticated(); }); + http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository()); http.httpBasic(); return http.build(); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/ErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/ErrorPageTests.java index e7c195432c..cb1e0115f7 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/ErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/ErrorPageTests.java @@ -21,6 +21,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; /** * Tests to ensure that the error page is accessible only to authorized users. @@ -44,9 +46,10 @@ class ErrorPageTests extends AbstractErrorPageTests { @Bean SecurityFilterChain configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> { - requests.antMatchers("/public/**").permitAll(); + requests.requestMatchers("/public/**").permitAll(); requests.anyRequest().fullyAuthenticated(); }); + http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository()); http.httpBasic(); http.formLogin((form) -> form.loginPage("/login").permitAll()); return http.build(); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/NoSessionErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/NoSessionErrorPageTests.java index b49592b8c7..242a2ce226 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/NoSessionErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/NoSessionErrorPageTests.java @@ -46,7 +46,7 @@ class NoSessionErrorPageTests extends AbstractErrorPageTests { SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests((requests) -> { - requests.antMatchers("/public/**").permitAll(); + requests.requestMatchers("/public/**").permitAll(); requests.anyRequest().authenticated(); }); http.httpBasic(); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java index 67e507487c..bfbffdbc12 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java @@ -96,7 +96,7 @@ class SampleWebSecureApplicationTests { SecurityFilterChain configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeHttpRequests((requests) -> { - requests.antMatchers("/public/**").permitAll(); + requests.requestMatchers("/public/**").permitAll(); requests.anyRequest().fullyAuthenticated(); }); http.httpBasic(); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/UnauthenticatedErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/UnauthenticatedErrorPageTests.java index 6cc7349962..ddfd954974 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/UnauthenticatedErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/UnauthenticatedErrorPageTests.java @@ -21,6 +21,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextRepository; /** * Tests for error page that permits access to all. @@ -44,10 +46,11 @@ class UnauthenticatedErrorPageTests extends AbstractUnauthenticatedErrorPageTest @Bean SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> { - requests.antMatchers("/error").permitAll(); - requests.antMatchers("/public/**").permitAll(); + requests.requestMatchers("/error").permitAll(); + requests.requestMatchers("/public/**").permitAll(); requests.anyRequest().authenticated(); }); + http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository()); http.httpBasic(); return http.build(); }