mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-23 12:32:13 +00:00
Avoid unnecessary instantiation of HttpSecurity when a SecurityFilterChain bean is provided
Signed-off-by: DingHao <dh.hiekn@gmail.com>
This commit is contained in:
parent
6cfc372f70
commit
c631afcf5b
@ -22,6 +22,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import jakarta.servlet.Filter;
|
import jakarta.servlet.Filter;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
@ -74,9 +75,6 @@ public class WebSecurityConfiguration implements ImportAware {
|
|||||||
|
|
||||||
private List<WebSecurityCustomizer> webSecurityCustomizers = Collections.emptyList();
|
private List<WebSecurityCustomizer> webSecurityCustomizers = Collections.emptyList();
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private HttpSecurity httpSecurity;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public static DelegatingApplicationListener delegatingApplicationListener() {
|
public static DelegatingApplicationListener delegatingApplicationListener() {
|
||||||
return new DelegatingApplicationListener();
|
return new DelegatingApplicationListener();
|
||||||
@ -94,14 +92,15 @@ public class WebSecurityConfiguration implements ImportAware {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
|
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
|
||||||
public Filter springSecurityFilterChain() throws Exception {
|
public Filter springSecurityFilterChain(ObjectProvider<HttpSecurity> provider) throws Exception {
|
||||||
boolean hasFilterChain = !this.securityFilterChains.isEmpty();
|
boolean hasFilterChain = !this.securityFilterChains.isEmpty();
|
||||||
if (!hasFilterChain) {
|
if (!hasFilterChain) {
|
||||||
this.webSecurity.addSecurityFilterChainBuilder(() -> {
|
this.webSecurity.addSecurityFilterChainBuilder(() -> {
|
||||||
this.httpSecurity.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated());
|
HttpSecurity httpSecurity = provider.getObject();
|
||||||
this.httpSecurity.formLogin(Customizer.withDefaults());
|
httpSecurity.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated());
|
||||||
this.httpSecurity.httpBasic(Customizer.withDefaults());
|
httpSecurity.formLogin(Customizer.withDefaults());
|
||||||
return this.httpSecurity.build();
|
httpSecurity.httpBasic(Customizer.withDefaults());
|
||||||
|
return httpSecurity.build();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
|
for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2024 the original author or authors.
|
* Copyright 2002-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -27,8 +27,10 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
@ -326,6 +328,12 @@ public class WebSecurityConfigurationTests {
|
|||||||
.isInstanceOf(IllegalArgumentException.class);
|
.isInstanceOf(IllegalArgumentException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void avoidUnnecessaryHttpSecurityInstantiationWhenProvideOneSecurityFilterChain() {
|
||||||
|
this.spring.register(SecurityFilterChainConfig.class).autowire();
|
||||||
|
assertThat(this.spring.getContext().getBean(CustomBeanPostProcessor.class).instantiationCount).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertAnotherUserPermission(WebInvocationPrivilegeEvaluator privilegeEvaluator) {
|
private void assertAnotherUserPermission(WebInvocationPrivilegeEvaluator privilegeEvaluator) {
|
||||||
Authentication anotherUser = new TestingAuthenticationToken("anotherUser", "password", "ROLE_ANOTHER");
|
Authentication anotherUser = new TestingAuthenticationToken("anotherUser", "password", "ROLE_ANOTHER");
|
||||||
assertThat(privilegeEvaluator.isAllowed("/user", anotherUser)).isFalse();
|
assertThat(privilegeEvaluator.isAllowed("/user", anotherUser)).isFalse();
|
||||||
@ -347,6 +355,32 @@ public class WebSecurityConfigurationTests {
|
|||||||
assertThat(privilegeEvaluator.isAllowed("/another", user)).isTrue();
|
assertThat(privilegeEvaluator.isAllowed("/another", user)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@Import(CustomBeanPostProcessor.class)
|
||||||
|
static class SecurityFilterChainConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
return http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CustomBeanPostProcessor implements BeanPostProcessor {
|
||||||
|
|
||||||
|
int instantiationCount = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||||
|
if (bean instanceof HttpSecurity) {
|
||||||
|
this.instantiationCount++;
|
||||||
|
}
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@Import(AuthenticationTestConfiguration.class)
|
@Import(AuthenticationTestConfiguration.class)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user