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