Skip to content

Commit c2635ba

Browse files
committed
Apply configurers from spring.factories to HttpSecurity bean
Closes gh-10814
1 parent 4492e5b commit c2635ba

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -17,18 +17,21 @@
1717
package org.springframework.security.config.annotation.web.configuration;
1818

1919
import java.util.HashMap;
20+
import java.util.List;
2021
import java.util.Map;
2122

2223
import org.springframework.beans.factory.annotation.Autowired;
2324
import org.springframework.context.ApplicationContext;
2425
import org.springframework.context.annotation.Bean;
2526
import org.springframework.context.annotation.Configuration;
2627
import org.springframework.context.annotation.Scope;
28+
import org.springframework.core.io.support.SpringFactoriesLoader;
2729
import org.springframework.security.authentication.AuthenticationManager;
2830
import org.springframework.security.config.annotation.ObjectPostProcessor;
2931
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
3032
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
3133
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
34+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
3235
import org.springframework.security.config.annotation.web.configurers.DefaultLoginPageConfigurer;
3336
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
3437

@@ -97,6 +100,7 @@ HttpSecurity httpSecurity() throws Exception {
97100
.apply(new DefaultLoginPageConfigurer<>());
98101
http.logout(withDefaults());
99102
// @formatter:on
103+
applyDefaultConfigurers(http);
100104
return http;
101105
}
102106

@@ -105,6 +109,15 @@ private AuthenticationManager authenticationManager() throws Exception {
105109
: this.authenticationConfiguration.getAuthenticationManager();
106110
}
107111

112+
private void applyDefaultConfigurers(HttpSecurity http) throws Exception {
113+
ClassLoader classLoader = this.context.getClassLoader();
114+
List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader
115+
.loadFactories(AbstractHttpConfigurer.class, classLoader);
116+
for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
117+
http.apply(configurer);
118+
}
119+
}
120+
108121
private Map<Class<?>, Object> createSharedObjects() {
109122
Map<Class<?>, Object> sharedObjects = new HashMap<>();
110123
sharedObjects.put(ApplicationContext.class, this.context);

config/src/test/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfigurationTests.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -16,22 +16,28 @@
1616

1717
package org.springframework.security.config.annotation.web.configuration;
1818

19+
import java.util.Arrays;
1920
import java.util.concurrent.Callable;
2021

2122
import javax.servlet.http.HttpServletRequest;
2223

2324
import com.google.common.net.HttpHeaders;
2425
import org.junit.jupiter.api.Test;
2526
import org.junit.jupiter.api.extension.ExtendWith;
27+
import org.mockito.Mock;
28+
import org.mockito.MockedStatic;
29+
import org.mockito.junit.jupiter.MockitoExtension;
2630

2731
import org.springframework.beans.factory.BeanCreationException;
2832
import org.springframework.beans.factory.annotation.Autowired;
2933
import org.springframework.context.annotation.Bean;
3034
import org.springframework.context.annotation.Configuration;
35+
import org.springframework.core.io.support.SpringFactoriesLoader;
3136
import org.springframework.mock.web.MockHttpSession;
3237
import org.springframework.security.access.AccessDeniedException;
3338
import org.springframework.security.authentication.TestingAuthenticationToken;
3439
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
40+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
3541
import org.springframework.security.config.test.SpringTestContext;
3642
import org.springframework.security.config.test.SpringTestContextExtension;
3743
import org.springframework.security.core.context.SecurityContextHolder;
@@ -67,14 +73,17 @@
6773
*
6874
* @author Eleftheria Stein
6975
*/
70-
@ExtendWith(SpringTestContextExtension.class)
76+
@ExtendWith({ MockitoExtension.class, SpringTestContextExtension.class })
7177
public class HttpSecurityConfigurationTests {
7278

7379
public final SpringTestContext spring = new SpringTestContext(this);
7480

7581
@Autowired
7682
private MockMvc mockMvc;
7783

84+
@Mock
85+
private MockedStatic<SpringFactoriesLoader> springFactoriesLoader;
86+
7887
@Test
7988
public void postWhenDefaultFilterChainBeanThenRespondsWithForbidden() throws Exception {
8089
this.spring.register(DefaultWithFilterChainConfig.class).autowire();
@@ -220,6 +229,17 @@ public void configureWhenAuthorizeHttpRequestsAfterAuthorizeRequestThenException
220229
"authorizeHttpRequests cannot be used in conjunction with authorizeRequests. Please select just one.");
221230
}
222231

232+
@Test
233+
public void configureWhenDefaultConfigurerAsSpringFactoryThenDefaultConfigurerApplied() {
234+
DefaultConfigurer configurer = new DefaultConfigurer();
235+
this.springFactoriesLoader.when(
236+
() -> SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader()))
237+
.thenReturn(Arrays.asList(configurer));
238+
this.spring.register(DefaultWithFilterChainConfig.class).autowire();
239+
assertThat(configurer.init).isTrue();
240+
assertThat(configurer.configure).isTrue();
241+
}
242+
223243
@RestController
224244
static class NameController {
225245

@@ -349,4 +369,22 @@ void user(HttpServletRequest request) {
349369

350370
}
351371

372+
static class DefaultConfigurer extends AbstractHttpConfigurer<DefaultConfigurer, HttpSecurity> {
373+
374+
boolean init;
375+
376+
boolean configure;
377+
378+
@Override
379+
public void init(HttpSecurity builder) {
380+
this.init = true;
381+
}
382+
383+
@Override
384+
public void configure(HttpSecurity builder) {
385+
this.configure = true;
386+
}
387+
388+
}
389+
352390
}

0 commit comments

Comments
 (0)