Search code examples
springspring-bootswaggerspringfox

Spring: Using Oauth2 and HttpBasicAuth together


I'm using Spring Boot 2.0.0

For securing my REST API i'm using Oauth2 with JWT, which works perfectly fine.

The problem is:

I'm also using Springfox Swagger which should be secured by BasicAuth. So that the user is challenged if he points his browser to /swagger-ui.html Therefore i got two configuration files:

SecurityConfig

@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {

    @Throws(Exception::class)
    override fun configure(web: WebSecurity) {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**")
    }

    @Throws(Exception::class)
    override fun configure(auth: AuthenticationManagerBuilder) {
        auth.inMemoryAuthentication()
                //user: "user", password: "Passw0rd!"
                .withUser("user")
                .password("\$2a\$04\$DDYoNw1VAYt64.zU.NsUpOdvjZ3OVrGXJAyARkraaS00h322eL2iy")
                .roles("ADMIN")
    }
}

ResourceServerConfig

@Configuration
@EnableResourceServer
class ResourceServerConfig : ResourceServerConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
        super.configure(http)
        http.httpBasic().and().cors().and().csrf().disable()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .antMatcher("/swagger-ui.html**")
                .authorizeRequests().anyRequest().hasRole("ADMIN")

    }
}

I think the OAuth2AuthorizationServerConfig is not needed here.

The shown configuration (of course) doesn't work, so the question is: Is it possible to mix BasicAuth and Oauth2?


Solution

  • Ok, i more or less found an answer to my question:

    SecurityConfig

    @Configuration
    @EnableWebSecurity
    class SecurityConfig : WebSecurityConfigurerAdapter() {
    
        @Throws(Exception::class)
        override fun configure(auth: AuthenticationManagerBuilder) {
            auth.inMemoryAuthentication()
                    //user: "user", password: "Passw0rd!"
                    .withUser("user")
                    .password("...")
                    .roles("ADMIN")
        }
    
        override fun configure(http: HttpSecurity) {
            http.csrf()
                    .and()
                    .httpBasic()
                    .and()
                    .authorizeRequests()
                    .antMatchers(
                            "/swagger-ui.html**").hasRole("ADMIN")
                    .antMatchers(
                            "/v2/api-docs",
                            "/swagger-resources/**",
                            "/configuration/security", "/webjars/**"
                    ).permitAll()
        }
    }
    

    ResourceServerConfig

    @Configuration
    @EnableResourceServer
    class ResourceServerConfig : ResourceServerConfigurerAdapter() {
    
        override fun configure(http: HttpSecurity) {
            http.cors().and()
                    .antMatcher("/api")
                    .authorizeRequests().antMatchers("/api/**").authenticated()
        }
    }
    

    I'm using antMatcher in the ResourceServerConfig to protect only the /api/** paths with oauth2.

    The BasicAuth part happens in SecurityConfig. The current solution only applies the BasicAuth only to the /swagger-ui.html endpoint. The other swagger resources are public visible.

    Does anyone know a way to also protect /v2/api-docs?