Skip to content

Commit 0818f27

Browse files
mbhavephilwebb
authored andcommitted
Configure WebSecurity using WebSecurityCustomizer
Replace `WebSecurityConfigurer` and `WebSecurityConfigurerAdapter` configurations with `WebSecurityCustomizer` or `SecurityFilterChain` beans. Closes gh-23421
1 parent 79b98c9 commit 0818f27

File tree

20 files changed

+136
-118
lines changed

20 files changed

+136
-118
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -64,6 +64,7 @@
6464
import org.springframework.http.HttpMethod;
6565
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
6666
import org.springframework.security.config.annotation.web.builders.WebSecurity;
67+
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
6768
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
6869
import org.springframework.web.cors.CorsConfiguration;
6970
import org.springframework.web.servlet.DispatcherServlet;
@@ -158,18 +159,23 @@ private CorsConfiguration getCorsConfiguration() {
158159
* specific paths. The Cloud foundry endpoints are protected by their own security
159160
* interceptor.
160161
*/
161-
@ConditionalOnClass(WebSecurity.class)
162-
@Order(SecurityProperties.IGNORED_ORDER)
162+
@ConditionalOnClass({ WebSecurityCustomizer.class, WebSecurity.class })
163163
@Configuration(proxyBeanMethods = false)
164-
public static class IgnoredPathsWebSecurityConfigurer implements WebSecurityConfigurer<WebSecurity> {
164+
public static class IgnoredCloudFoundryPathsWebSecurityConfiguration {
165165

166-
@Override
167-
public void init(WebSecurity builder) throws Exception {
168-
builder.ignoring().requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**"));
166+
@Bean
167+
IgnoredCloudFoundryPathsWebSecurityCustomizer ignoreCloudFoundryPathsWebSecurityCustomizer() {
168+
return new IgnoredCloudFoundryPathsWebSecurityCustomizer();
169169
}
170170

171+
}
172+
173+
@Order(SecurityProperties.IGNORED_ORDER)
174+
static class IgnoredCloudFoundryPathsWebSecurityCustomizer implements WebSecurityCustomizer {
175+
171176
@Override
172-
public void configure(WebSecurity builder) throws Exception {
177+
public void customize(WebSecurity web) {
178+
web.ignoring().requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**"));
173179
}
174180

175181
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration;
3232
import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration;
3333
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
34+
import org.springframework.context.annotation.Bean;
3435
import org.springframework.context.annotation.Configuration;
3536
import org.springframework.security.config.Customizer;
3637
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -49,7 +50,7 @@
4950
* @since 2.1.0
5051
*/
5152
@Configuration(proxyBeanMethods = false)
52-
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
53+
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
5354
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
5455
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
5556
@AutoConfigureBefore(SecurityAutoConfiguration.class)
@@ -58,19 +59,15 @@
5859
OAuth2ResourceServerAutoConfiguration.class, Saml2RelyingPartyAutoConfiguration.class })
5960
public class ManagementWebSecurityAutoConfiguration {
6061

61-
@Configuration(proxyBeanMethods = false)
62-
static class ManagementWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
63-
64-
@Override
65-
protected void configure(HttpSecurity http) throws Exception {
66-
http.authorizeRequests((requests) -> {
67-
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)).permitAll();
68-
requests.anyRequest().authenticated();
69-
});
70-
http.formLogin(Customizer.withDefaults());
71-
http.httpBasic(Customizer.withDefaults());
72-
}
73-
62+
@Bean
63+
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
64+
http.authorizeRequests((requests) -> {
65+
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)).permitAll();
66+
requests.anyRequest().authenticated();
67+
});
68+
http.formLogin(Customizer.withDefaults());
69+
http.httpBasic(Customizer.withDefaults());
70+
return http.build();
7471
}
7572

7673
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
*/
5757
class ManagementWebSecurityAutoConfigurationTests {
5858

59+
private static final String MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN = "managementSecurityFilterChain";
60+
5961
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner().withConfiguration(
6062
AutoConfigurations.of(HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
6163
InfoEndpointAutoConfiguration.class, EnvironmentEndpointAutoConfiguration.class,
@@ -65,6 +67,7 @@ class ManagementWebSecurityAutoConfigurationTests {
6567
@Test
6668
void permitAllForHealth() {
6769
this.contextRunner.run((context) -> {
70+
assertThat(context).hasBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN);
6871
HttpStatus status = getResponseStatus(context, "/actuator/health");
6972
assertThat(status).isEqualTo(HttpStatus.OK);
7073
});
@@ -127,8 +130,8 @@ void backsOffIfSecurityFilterChainBeanIsPresent() {
127130
void backOffIfOAuth2ResourceServerAutoConfigurationPresent() {
128131
this.contextRunner.withConfiguration(AutoConfigurations.of(OAuth2ResourceServerAutoConfiguration.class))
129132
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://authserver")
130-
.run((context) -> assertThat(context).doesNotHaveBean(
131-
ManagementWebSecurityAutoConfiguration.ManagementWebSecurityConfigurerAdapter.class));
133+
.run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class)
134+
.doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN));
132135
}
133136

134137
@Test
@@ -139,8 +142,8 @@ void backOffIfSaml2RelyingPartyAutoConfigurationPresent() {
139142
"spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.sign-request=false",
140143
"spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
141144
"spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location")
142-
.run((context) -> assertThat(context).doesNotHaveBean(
143-
ManagementWebSecurityAutoConfiguration.ManagementWebSecurityConfigurerAdapter.class));
145+
.run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class)
146+
.doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN));
144147
}
145148

146149
private HttpStatus getResponseStatus(AssertableWebApplicationContext context, String path)

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2WebSecurityConfiguration.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,16 @@ OAuth2AuthorizedClientRepository authorizedClientRepository(OAuth2AuthorizedClie
5454
}
5555

5656
@Configuration(proxyBeanMethods = false)
57-
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
57+
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
5858
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
59-
static class OAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
59+
static class OAuth2SecurityFilterChainConfiguration {
6060

61-
@Override
62-
protected void configure(HttpSecurity http) throws Exception {
61+
@Bean
62+
SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
6363
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
6464
http.oauth2Login(Customizer.withDefaults());
6565
http.oauth2Client();
66+
return http.build();
6667
}
6768

6869
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerJwtConfiguration.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
* @author HaiTao Zhang
5151
*/
5252
@Configuration(proxyBeanMethods = false)
53-
5453
class OAuth2ResourceServerJwtConfiguration {
5554

5655
@Configuration(proxyBeanMethods = false)
@@ -98,22 +97,16 @@ JwtDecoder jwtDecoderByIssuerUri() {
9897
}
9998

10099
@Configuration(proxyBeanMethods = false)
101-
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
100+
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
102101
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
103-
static class OAuth2WebSecurityConfigurerAdapter {
102+
static class OAuth2SecurityFilterChainConfiguration {
104103

105104
@Bean
106105
@ConditionalOnBean(JwtDecoder.class)
107-
WebSecurityConfigurerAdapter jwtDecoderWebSecurityConfigurerAdapter() {
108-
return new WebSecurityConfigurerAdapter() {
109-
110-
@Override
111-
protected void configure(HttpSecurity http) throws Exception {
112-
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
113-
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
114-
}
115-
116-
};
106+
SecurityFilterChain jwtSecurityFilterChain(HttpSecurity http) throws Exception {
107+
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
108+
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
109+
return http.build();
117110
}
118111

119112
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,14 @@ NimbusOpaqueTokenIntrospector opaqueTokenIntrospector(OAuth2ResourceServerProper
5656
@Configuration(proxyBeanMethods = false)
5757
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
5858
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
59-
static class OAuth2WebSecurityConfigurerAdapter {
59+
static class OAuth2SecurityFilterChainConfiguration {
6060

6161
@Bean
6262
@ConditionalOnBean(OpaqueTokenIntrospector.class)
63-
WebSecurityConfigurerAdapter opaqueTokenWebSecurityConfigurerAdapter() {
64-
return new WebSecurityConfigurerAdapter() {
65-
66-
@Override
67-
protected void configure(HttpSecurity http) throws Exception {
68-
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
69-
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
70-
}
71-
72-
};
63+
SecurityFilterChain opaqueTokenSecurityFilterChain(HttpSecurity http) throws Exception {
64+
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
65+
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
66+
return http.build();
7367
}
7468

7569
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/Oauth2ResourceServerConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ class Oauth2ResourceServerConfiguration {
3232
@Configuration(proxyBeanMethods = false)
3333
@ConditionalOnClass(JwtDecoder.class)
3434
@Import({ OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration.class,
35-
OAuth2ResourceServerJwtConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
35+
OAuth2ResourceServerJwtConfiguration.OAuth2SecurityFilterChainConfiguration.class })
3636
static class JwtConfiguration {
3737

3838
}
3939

4040
@Configuration(proxyBeanMethods = false)
4141
@Import({ OAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration.class,
42-
OAuth2ResourceServerOpaqueTokenConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
42+
OAuth2ResourceServerOpaqueTokenConfiguration.OAuth2SecurityFilterChainConfiguration.class })
4343
static class OpaqueTokenConfiguration {
4444

4545
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2LoginConfiguration.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2020
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2121
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
22+
import org.springframework.context.annotation.Bean;
2223
import org.springframework.context.annotation.Configuration;
2324
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
2425
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@@ -32,19 +33,15 @@
3233
* @author Madhura Bhave
3334
*/
3435
@Configuration(proxyBeanMethods = false)
35-
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
36+
@ConditionalOnMissingBean({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
3637
@ConditionalOnBean(RelyingPartyRegistrationRepository.class)
37-
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
38+
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
3839
class Saml2LoginConfiguration {
3940

40-
@Configuration(proxyBeanMethods = false)
41-
static class Saml2LoginConfigurerAdapter extends WebSecurityConfigurerAdapter {
42-
43-
@Override
44-
protected void configure(HttpSecurity http) throws Exception {
45-
http.authorizeRequests((requests) -> requests.anyRequest().authenticated()).saml2Login();
46-
}
47-
41+
@Bean
42+
SecurityFilterChain samlSecurityFilterChain(HttpSecurity http) throws Exception {
43+
http.authorizeRequests((requests) -> requests.anyRequest().authenticated()).saml2Login();
44+
return http.build();
4845
}
4946

5047
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
2222
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
2323
import org.springframework.boot.autoconfigure.security.SecurityProperties;
24+
import org.springframework.context.annotation.Bean;
2425
import org.springframework.context.annotation.Configuration;
2526
import org.springframework.core.annotation.Order;
27+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
2628
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
2729
import org.springframework.security.web.SecurityFilterChain;
2830

@@ -37,15 +39,16 @@
3739
* @author Madhura Bhave
3840
*/
3941
@Configuration(proxyBeanMethods = false)
40-
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
41-
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
42+
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
43+
@ConditionalOnMissingBean({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
4244
@ConditionalOnWebApplication(type = Type.SERVLET)
4345
class SpringBootWebSecurityConfiguration {
4446

45-
@Configuration(proxyBeanMethods = false)
47+
@Bean
4648
@Order(SecurityProperties.BASIC_AUTH_ORDER)
47-
static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {
48-
49+
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
50+
http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
51+
return http.build();
4952
}
5053

5154
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2WebSecurityConfigurationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void configurationRegistersAuthorizedClientRepositoryBean() {
117117
}
118118

119119
@Test
120-
void securityConfigurerBacksOffBacksOffWhenOtherWebSecurityAdapterPresent() {
120+
void securityFilterChainConfigBacksOffWhenOtherWebSecurityAdapterPresent() {
121121
this.contextRunner
122122
.withUserConfiguration(TestWebSecurityConfigurerConfig.class, OAuth2WebSecurityConfiguration.class)
123123
.run((context) -> {
@@ -128,7 +128,7 @@ void securityConfigurerBacksOffBacksOffWhenOtherWebSecurityAdapterPresent() {
128128
}
129129

130130
@Test
131-
void securityConfigurerBacksOffBacksOffWhenOtherSecurityFilterChainBeanPresent() {
131+
void securityFilterChainConfigBacksOffWhenOtherSecurityFilterChainBeanPresent() {
132132
this.contextRunner
133133
.withUserConfiguration(TestSecurityFilterChainConfig.class, OAuth2WebSecurityConfiguration.class)
134134
.run((context) -> {
@@ -139,7 +139,7 @@ void securityConfigurerBacksOffBacksOffWhenOtherSecurityFilterChainBeanPresent()
139139
}
140140

141141
@Test
142-
void securityConfigurerBacksOffConditionalOnSecurityFilterChainClass() {
142+
void securityFilterChainConfigConditionalOnSecurityFilterChainClass() {
143143
this.contextRunner
144144
.withUserConfiguration(ClientRegistrationRepositoryConfiguration.class,
145145
OAuth2WebSecurityConfiguration.class)

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.core.io.Resource;
3939
import org.springframework.security.config.BeanIds;
4040
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
41+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
4142
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
4243
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
4344
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
@@ -220,6 +221,11 @@ RelyingPartyRegistrationRepository testRegistrationRepository() {
220221

221222
}
222223

224+
@EnableWebSecurity
225+
static class WebSecurityEnablerConfiguration {
226+
227+
}
228+
223229
@Configuration(proxyBeanMethods = false)
224230
static class WebSecurityConfigurerAdapterConfiguration {
225231

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ void enableWebSecurityIsConditionalOnClass() {
7676
.run((context) -> assertThat(context).doesNotHaveBean("springSecurityFilterChain"));
7777
}
7878

79+
@Test
80+
void filterChainBeanIsConditionalOnClassSecurityFilterChain() {
81+
this.contextRunner.withClassLoader(new FilteredClassLoader(SecurityFilterChain.class))
82+
.run((context) -> assertThat(context).doesNotHaveBean(SecurityFilterChain.class));
83+
}
84+
7985
@Test
8086
void securityConfigurerBacksOffWhenOtherSecurityFilterChainBeanPresent() {
8187
this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class).run((context) -> {

0 commit comments

Comments
 (0)