Hello. Thank you the wonderful project.
As I can gather from the documentation currently available here, multiple SecurityFilterChain can be configured in FilterChainProxy.
However, I am having a very time in figuring out how exactly do we end up with multiple SecurityFilterChains because I think there is lack in clarity in documenation stating when a SecurityFilterChain ends and another begins.
Lets take an example of code I saw in another issue.
Does a new SecurityFilterChain is created whenever HttpSecurity#and is invoked or all the antMatchers call end up being a new SecurityFilterChain ?
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(2)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, HttpPathStore.PING).permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/logout").hasRole("USER")
.antMatchers("/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin()
.loginProcessingUrl(HttpPathStore.LOGIN)
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll()
.and()
.logout()
.logoutUrl(HttpPathStore.LOGOUT)
.logoutSuccessUrl(HttpPathStore.LOGIN_FROM_LOGOUT)
.logoutSuccessHandler(logoutSuccessHandler)
.permitAll();
}
...
}
I find it confusing as I think this is not explained in enough detail and can be written a bit better to explain this concept.
Thank you.
Comment From: eleftherias
Thanks for bringing this up @gourav.
One thing that might help make this clearer is configuring the SecurityFilterChain as a bean, rather than extending WebSecurityConfigurerAdapter (see gh-8804).
This is something we're planning to add to our documentation.
I also see room for improvement in the Multiple HttpSecurity section of the reference docs.
Currently, there is no mention of multiple SecurityFilterChains in that section and I think it's something we should add.
Comment From: linghengqian
To be frank, I don't quite understand that Spring Security sample uses Multiple HttpSecurity with only SecurityFilterChain, and the DOC doesn't provide a corresponding example.
I understand the SecurityFilterChain and WebSecurityConfigurerAdapter should be compatible, But practice looks SecurityFilterChain and WebSecurityConfigurerAdapter cannot be configured at the same time, can only take one.
And SecurityFilterChain looks can't separate configuration configure (AuthenticationManagerBuilder auth) ? Is this also the missing part of DOC?
Comment From: p-daniil
To be frank, I don't quite understand that
Spring Security sampleusesMultiple HttpSecuritywith onlySecurityFilterChain, and the DOC doesn't provide a corresponding example. I understand theSecurityFilterChainandWebSecurityConfigurerAdaptershould be compatible, But practice looksSecurityFilterChainandWebSecurityConfigurerAdaptercannot be configured at the same time, can only take one. AndSecurityFilterChainlooks can't separate configurationconfigure (AuthenticationManagerBuilder auth)? Is this also the missing part of DOC?
I have discovered how to configure AuthenticationManager.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// Add authentication provider
http.authenticationProvider(...);
http.userDetailsService(...);
// Accessing full set of AuthenticationManagerBuilder methods
http.getSharedObject(AuthenticationManagerBuilder.class)
return http.build();
}
Accessing to full set of AuthenticationManagerBuilder methods is quite inconvenient. There is a method getAuthenticationRegistry(), but it is private.
To configure global authentication manager, you can use GlobalAuthenticationConfigurerAdapter
Comment From: eleftherias
@p-daniil If you are using Spring Security 5.6 you can configure the AuthenticationManager by supplying it to HttpSecurity.
http
.authenticationManager(customAuthenticationManager)
If you want the AuthenticationManager to be available throughout the application, you can register it as a @Bean
@Bean
public AuthenticationManager authenticationManager() {
return new CustomAuthenticationManager();
}
Comment From: eleftherias
This issue was fixed as part of #10003