Describe the bug
If a security configurer is added during builder's initializing lifecycle phase, if such configurer adds any other configurer to the builder then a ConcurrentModificationException
is thrown at https://github.com/spring-projects/spring-security/blob/9df3a57d9e3bea9c01c54a546ddca7bf5fe37050/config/src/main/java/org/springframework/security/config/annotation/AbstractConfiguredSecurityBuilder.java#L389-L391
since configurersAddedInInitializing
is being modified at https://github.com/spring-projects/spring-security/blob/9df3a57d9e3bea9c01c54a546ddca7bf5fe37050/config/src/main/java/org/springframework/security/config/annotation/AbstractConfiguredSecurityBuilder.java#L234-L236
To Reproduce Running this configuration:
@Configuration
@EnableWebSecurity
public class DemoSecurity {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.with(new FooConfigurer(), Customizer.withDefaults()).build();
}
static class FooConfigurer extends AbstractHttpConfigurer<FooConfigurer, HttpSecurity> {
@Override
public void init(HttpSecurity http) throws Exception {
http.with(new BarConfigurer(), Customizer.withDefaults());
}
}
static class BarConfigurer extends AbstractHttpConfigurer<BarConfigurer, HttpSecurity> {
@Override
public void init(HttpSecurity http) throws Exception {
http.formLogin(login -> login.loginPage("/login"));
}
}
}
throws:
java.util.ConcurrentModificationException: null
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1096) ~[na:na]
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1050) ~[na:na]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:389) ~[spring-security-config-6.4.5.jar:6.4.5]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:349) ~[spring-security-config-6.4.5.jar:6.4.5]
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:38) ~[spring-security-config-6.4.5.jar:6.4.5]
Expected behavior Since adding configurers during builder's initializing lifecycle phase is supported, I would expect it to allow this also for configurers that add others during initialization. The provided example is minimal, but on a more realistic scenario a custom configurer from a library might need to add others during its initialization.
Sample
https://github.com/heruan/spring-security-configurers
Comment From: heruan
Thanks @kse-music for the PR! I tested it and I can confirm it fixes the issue. Is this being back ported also to 6.3/6.4?
Comment From: heruan
@jzheaux is there anything I can further help with to get this fixed?
Comment From: heruan
This is still blocking our projects after we have introduced a custom security configurer, that uses another one. Does #17020 look good enough or does it need anything else to be reviewed and merged (and possibly backported)?
Comment From: rwinch
Thanks for creating this issue. I've closed it in favor of gh-17020