Configure WebSecurity using WebSecurityCustomizer

Replace `WebSecurityConfigurer` and `WebSecurityConfigurerAdapter`
configurations with `WebSecurityCustomizer` or `SecurityFilterChain`
beans.

Closes gh-23421
This commit is contained in:
Madhura Bhave
2020-08-14 11:09:37 -07:00
committed by Phillip Webb
parent 79b98c9edd
commit 0818f27f44
20 changed files with 136 additions and 118 deletions

View File

@@ -54,15 +54,16 @@ class OAuth2WebSecurityConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
static class OAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
static class OAuth2SecurityFilterChainConfiguration {
@Override
protected void configure(HttpSecurity http) throws Exception {
@Bean
SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2Login(Customizer.withDefaults());
http.oauth2Client();
return http.build();
}
}

View File

@@ -50,7 +50,6 @@ import org.springframework.security.web.SecurityFilterChain;
* @author HaiTao Zhang
*/
@Configuration(proxyBeanMethods = false)
class OAuth2ResourceServerJwtConfiguration {
@Configuration(proxyBeanMethods = false)
@@ -98,22 +97,16 @@ class OAuth2ResourceServerJwtConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
static class OAuth2WebSecurityConfigurerAdapter {
static class OAuth2SecurityFilterChainConfiguration {
@Bean
@ConditionalOnBean(JwtDecoder.class)
WebSecurityConfigurerAdapter jwtDecoderWebSecurityConfigurerAdapter() {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}
};
SecurityFilterChain jwtSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
}

View File

@@ -56,20 +56,14 @@ class OAuth2ResourceServerOpaqueTokenConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
static class OAuth2WebSecurityConfigurerAdapter {
static class OAuth2SecurityFilterChainConfiguration {
@Bean
@ConditionalOnBean(OpaqueTokenIntrospector.class)
WebSecurityConfigurerAdapter opaqueTokenWebSecurityConfigurerAdapter() {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
}
};
SecurityFilterChain opaqueTokenSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
return http.build();
}
}

View File

@@ -32,14 +32,14 @@ class Oauth2ResourceServerConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(JwtDecoder.class)
@Import({ OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration.class,
OAuth2ResourceServerJwtConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
OAuth2ResourceServerJwtConfiguration.OAuth2SecurityFilterChainConfiguration.class })
static class JwtConfiguration {
}
@Configuration(proxyBeanMethods = false)
@Import({ OAuth2ResourceServerOpaqueTokenConfiguration.OpaqueTokenIntrospectionClientConfiguration.class,
OAuth2ResourceServerOpaqueTokenConfiguration.OAuth2WebSecurityConfigurerAdapter.class })
OAuth2ResourceServerOpaqueTokenConfiguration.OAuth2SecurityFilterChainConfiguration.class })
static class OpaqueTokenConfiguration {
}

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.security.saml2;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@@ -32,19 +33,15 @@ import org.springframework.security.web.SecurityFilterChain;
* @author Madhura Bhave
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
@ConditionalOnMissingBean({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnBean(RelyingPartyRegistrationRepository.class)
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
class Saml2LoginConfiguration {
@Configuration(proxyBeanMethods = false)
static class Saml2LoginConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated()).saml2Login();
}
@Bean
SecurityFilterChain samlSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> requests.anyRequest().authenticated()).saml2Login();
return http.build();
}
}

View File

@@ -21,8 +21,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.SecurityFilterChain;
@@ -37,15 +39,16 @@ import org.springframework.security.web.SecurityFilterChain;
* @author Madhura Bhave
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnMissingBean({ WebSecurityConfigurerAdapter.class, SecurityFilterChain.class })
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
@ConditionalOnMissingBean({ SecurityFilterChain.class, WebSecurityConfigurerAdapter.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
@Configuration(proxyBeanMethods = false)
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
return http.build();
}
}

View File

@@ -117,7 +117,7 @@ class OAuth2WebSecurityConfigurationTests {
}
@Test
void securityConfigurerBacksOffBacksOffWhenOtherWebSecurityAdapterPresent() {
void securityFilterChainConfigBacksOffWhenOtherWebSecurityAdapterPresent() {
this.contextRunner
.withUserConfiguration(TestWebSecurityConfigurerConfig.class, OAuth2WebSecurityConfiguration.class)
.run((context) -> {
@@ -128,7 +128,7 @@ class OAuth2WebSecurityConfigurationTests {
}
@Test
void securityConfigurerBacksOffBacksOffWhenOtherSecurityFilterChainBeanPresent() {
void securityFilterChainConfigBacksOffWhenOtherSecurityFilterChainBeanPresent() {
this.contextRunner
.withUserConfiguration(TestSecurityFilterChainConfig.class, OAuth2WebSecurityConfiguration.class)
.run((context) -> {
@@ -139,7 +139,7 @@ class OAuth2WebSecurityConfigurationTests {
}
@Test
void securityConfigurerBacksOffConditionalOnSecurityFilterChainClass() {
void securityFilterChainConfigConditionalOnSecurityFilterChainClass() {
this.contextRunner
.withUserConfiguration(ClientRegistrationRepositoryConfiguration.class,
OAuth2WebSecurityConfiguration.class)

View File

@@ -38,6 +38,7 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
@@ -220,6 +221,11 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
@EnableWebSecurity
static class WebSecurityEnablerConfiguration {
}
@Configuration(proxyBeanMethods = false)
static class WebSecurityConfigurerAdapterConfiguration {

View File

@@ -76,6 +76,12 @@ class SecurityAutoConfigurationTests {
.run((context) -> assertThat(context).doesNotHaveBean("springSecurityFilterChain"));
}
@Test
void filterChainBeanIsConditionalOnClassSecurityFilterChain() {
this.contextRunner.withClassLoader(new FilteredClassLoader(SecurityFilterChain.class))
.run((context) -> assertThat(context).doesNotHaveBean(SecurityFilterChain.class));
}
@Test
void securityConfigurerBacksOffWhenOtherSecurityFilterChainBeanPresent() {
this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class).run((context) -> {