Skip to content

Cannot add security configurers during builder initialization #17011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
heruan opened this issue Apr 29, 2025 · 1 comment · May be fixed by #17020
Open

Cannot add security configurers during builder initialization #17011

heruan opened this issue Apr 29, 2025 · 1 comment · May be fixed by #17020
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug

Comments

@heruan
Copy link
Contributor

heruan commented Apr 29, 2025

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

@heruan heruan added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Apr 29, 2025
kse-music added a commit to kse-music/spring-security that referenced this issue Apr 30, 2025
@heruan
Copy link
Contributor Author

heruan commented May 6, 2025

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant