To effectively manage security in an application where certain areas need different protection, we can employ multiple filter chains alongside the securityMatcher
DSL method. This approach allows us to define distinct security configurations tailored to specific parts of the application, enhancing overall application security and control.
We can configure multiple HttpSecurity
instances just as we can have multiple <http>
blocks in XML. The key is to register multiple SecurityFilterChain
@Bean
s. The following example has a different configuration for URLs that begin with /api/
:
@Configuration
@EnableWebSecurity
public class MultiHttpSecurityConfig {
/** 1. Configure Authentication as usual.**/
@Bean
public UserDetailsService userDetailsService() throws Exception {
UserBuilder users = User.withDefaultPasswordEncoder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users.username("user").password("password").roles("USER").build());
manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());
return manager;
}
/** 2. Create an instance of SecurityFilterChain that contains @Order to specify which SecurityFilterChain should be considered first. **/
@Bean
@Order(1)
public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
http
/** 3. The http.securityMatcher() states that this HttpSecurity is applicable only to URLs that begin with /api/. **/
.securityMatcher("/api/**") //3
.authorizeHttpRequests(authorize -> authorize
.anyRequest().hasRole("ADMIN")
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
/** 4. Create another instance of SecurityFilterChain. If the URL does not begin with /api/, this configuration is used. This configuration is considered after apiFilterChain, since it has an @Order value after 1 (no @Order defaults to last). **/
@Bean
public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults());
return http.build();
}
}
Reference: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html