Home > Back-end >  Spring Security not working on any endpoint with multiple WebSecurityConfigurerAdapter implementatio
Spring Security not working on any endpoint with multiple WebSecurityConfigurerAdapter implementatio

Time:03-19

I'm trying to setup Spring Security in my application, which has 3 components:

  • REST API (under v1 path)
  • Spring Admin & actuator (under /admin path)
  • Docs (under /docs and /swagger-ui paths)

I want to setup security like this:

  • REST API secured with JWT token
  • Admin secured with HTTP basic
  • Docs unsecured (public resource)

I've tried to configure authentication for those 3 parts in separate implementations of WebSecurityConfigurerAdapter, and the result looks like this:

For REST API:

@Configuration
@EnableWebSecurity
@Order(1)
class ApiWebSecurityConfig : WebSecurityConfigurerAdapter() {

    // FIXME: Temporary override to disable auth
    public override fun configure(http: HttpSecurity) {
        http
            .antMatcher("/v1/*")
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                    .anyRequest().permitAll()
                .and()             
                    .csrf().disable()
        }
    }

For Spring Admin:

@Configuration
@EnableWebSecurity
@Order(2)
class AdminWebSecurityConfig(
    private val adminServerProperties: AdminServerProperties
) : WebSecurityConfigurerAdapter() {

    public override fun configure(http: HttpSecurity) {
        http.antMatcher("${adminServerProperties.contextPath}/**")
                .authorizeRequests()
                .antMatchers("${adminServerProperties.contextPath}/assets/**").permitAll()
                .antMatchers("${adminServerProperties.contextPath}/login").permitAll()
                .anyRequest()
                .authenticated()
            .and()
                .cors()
            .and()
                .formLogin()
                .loginPage("${adminServerProperties.contextPath}/login")
            .and()
                .logout()
                .logoutUrl("${adminServerProperties.contextPath}/logout")
            .and()
                .httpBasic()
            .and()
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringRequestMatchers(
                     AntPathRequestMatcher("${adminServerProperties.contextPath}/instances", HttpMethod.POST.toString()),
                     AntPathRequestMatcher("${adminServerProperties.contextPath}/instances/*", HttpMethod.DELETE.toString()),
                     AntPathRequestMatcher("${adminServerProperties.contextPath}/actuator/**")
                )
    }

    @Bean
    fun corsConfigurationSource(): CorsConfigurationSource = UrlBasedCorsConfigurationSource().apply {
        registerCorsConfiguration("/**", CorsConfiguration().apply {
            allowedOrigins = listOf("*")
            allowedMethods = listOf("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH")
            allowCredentials = true
            allowedHeaders = listOf("Authorization", "Cache-Control", "Content-Type")
        })
     }
}

And for public docs:

@Configuration
@EnableWebSecurity
@Order(3)
class DocsWebSecurityConfig : WebSecurityConfigurerAdapter() {

    public override fun configure(http: HttpSecurity) {
        http
            .requestMatchers()
            .antMatchers("/swagger-ui/**", "/docs/**", "/docs-oas3/**")
            .and()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
    }
}

And my main application class looks like this:

@SpringBootApplication
@EnableAdminServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@EnableConfigurationProperties(FirebaseConfigurationProperties::class, JwtConfigurationProperties::class)
class HldpDeviceManagementApplication

fun main(args: Array<String>) {
    runApplication<HldpDeviceManagementApplication>(*args)
}

When I run the application, there's no error or any security information, besides this log output:

Will not secure Ant [pattern='/v1/**']
Will not secure Ant [pattern='/admin/**']
Will not secure Or [Ant [pattern='/swagger-ui/**'], Ant [pattern='/docs/**'], Ant [pattern='/docs-oas3/**']]

Any suggestion why doesn't the configuration work? Or maybe another way I can secure the application like this? I've tried doing a few changes in the configuration, but nothing seems to help.

CodePudding user response:

You didn't mention when it doesn't work, is it when you make a request, or on application startup? However, I can help you with your configuration and get the information needed to solve the problem.

I'll try to simplify your configuration with the new way to configure HttpSecurity, by exposing a SecurityFilterChain bean.

@Configuration
public class SecurityConfiguration {

    @Bean
    @Order(0)
    public SecurityFilterChain api(HttpSecurity http) throws Exception {
         http
            .requestMatchers(requests -> requests.antMatchers("/v1/**"))
            ...
        // the rest of the configuration
        return http.build();
    }

    @Bean
    @Order(1)
    public SecurityFilterChain admin(HttpSecurity http) throws Exception {
        http
            .requestMatchers(requests -> requests.antMatchers("/admin/**"))
            ...
        // the rest of the configuration
        return http.build();
    }

    @Bean
    @Order(2)
    public SecurityFilterChain docs(HttpSecurity http) throws Exception {
        http
            .requestMatchers(requests -> requests.antMatchers("/docs/**"))
            ...
        // the rest of the configuration
        return http.build();
    }

}

This is in Java, but you can adapt to Kotlin easily, I'm sorry to not provide it in Kotlin already. With this simplified configuration, now you can add logging.level.org.springframework.security=TRACE to your application.properties file and check what Spring Security is doing by reading the logs.

CodePudding user response:

I've found the problem - it's a bug in the latest version of Spring: https://github.com/spring-projects/spring-security/issues/10909

  • Related