Skip to content

Cannot add security configurers during builder initialization #17011

Open
@heruan

Description

@heruan

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

for (SecurityConfigurer<O, B> configurer : this.configurersAddedInInitializing) {
configurer.init((B) this);
}

since configurersAddedInInitializing is being modified at
if (this.buildState.isInitializing()) {
this.configurersAddedInInitializing.add(configurer);
}

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions