Skip to content

Commit 3ffd2a3

Browse files
kse-musicrwinch
authored andcommitted
Support add nested security configurers during builder initialization
Closes gh-17011 Signed-off-by: DingHao <dh.hiekn@gmail.com>
1 parent 82fa658 commit 3ffd2a3

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

config/src/main/java/org/springframework/security/config/annotation/AbstractConfiguredSecurityBuilder.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -49,6 +49,7 @@
4949
* @param <O> The object that this builder returns
5050
* @param <B> The type of this builder (that is returned by the base class)
5151
* @author Rob Winch
52+
* @author DingHao
5253
* @see WebSecurity
5354
*/
5455
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
@@ -364,8 +365,10 @@ private void init() throws Exception {
364365
for (SecurityConfigurer<O, B> configurer : configurers) {
365366
configurer.init((B) this);
366367
}
367-
for (SecurityConfigurer<O, B> configurer : this.configurersAddedInInitializing) {
368-
configurer.init((B) this);
368+
while (!this.configurersAddedInInitializing.isEmpty()) {
369+
for (SecurityConfigurer<O, B> configurer : getConfigurersInInitializing()) {
370+
configurer.init((B) this);
371+
}
369372
}
370373
}
371374

@@ -385,6 +388,12 @@ private Collection<SecurityConfigurer<O, B>> getConfigurers() {
385388
return result;
386389
}
387390

391+
private List<SecurityConfigurer<O, B>> getConfigurersInInitializing() {
392+
List<SecurityConfigurer<O, B>> result = new ArrayList<>(this.configurersAddedInInitializing);
393+
this.configurersAddedInInitializing.clear();
394+
return result;
395+
}
396+
388397
/**
389398
* Determines if the object is unbuilt.
390399
* @return true, if unbuilt else false

config/src/test/java/org/springframework/security/config/annotation/web/AbstractConfiguredSecurityBuilderTests.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 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.
@@ -163,6 +163,34 @@ public void withWhenDuplicateConfigurerAddedThenDuplicateConfigurerRemoved() thr
163163
assertThat(this.builder.getConfigurers(TestSecurityConfigurer.class)).hasSize(1);
164164
}
165165

166+
@Test
167+
public void withWhenConfigurerAddInitializing() throws Exception {
168+
this.builder.with(new FooConfigurer(), Customizer.withDefaults());
169+
assertThat(this.builder.build()).isEqualTo("success");
170+
}
171+
172+
private static class FooConfigurer extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
173+
174+
@Override
175+
public void init(TestConfiguredSecurityBuilder builder) throws Exception {
176+
builder.with(new BarConfigurer(), Customizer.withDefaults());
177+
}
178+
179+
}
180+
181+
private static class BarConfigurer extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
182+
183+
@Override
184+
public void init(TestConfiguredSecurityBuilder http) throws Exception {
185+
http.with(new CooConfigurer(), Customizer.withDefaults());
186+
}
187+
188+
}
189+
190+
private static class CooConfigurer extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
191+
192+
}
193+
166194
private static class ApplyAndRemoveSecurityConfigurer
167195
extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
168196

0 commit comments

Comments
 (0)