Add Swagger Basic AUTH to Spring Boot App

Cortlendt picture Cortlendt · Apr 25, 2018 · Viewed 11.9k times · Source

Requirements:

  • Spring Boot application with Springfox
  • Add BASIC authentication to Swagger
  • Pass on all other requests

Code: implemented

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/swagger-resources/*", "*.html", "/api/v1/swagger.json")
                .hasAuthority("SWAGGER")
                .anyRequest().permitAll()
            .and()
                .httpBasic()
            .and()
                .csrf().disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password("admin").authorities("SWAGGER");
    }
}

This code however does not work - you can freely browse /swagger-ui.html#/ without any authentcation.

Question is - why BASIC auth and user do not apply to swagger ui endpoint?

Answer

TwiN picture TwiN · Apr 25, 2018

You should use the .authenticated() instead of .permitAll():

.authorizeRequests()
    .antMatchers("/swagger-resources/*", "*.html", "/api/v1/swagger.json")
        .hasRole("SWAGGER")
    .anyRequest()
        .authenticated()

This will:

  • Restrict access to all resources matching /swagger-resources/*, *.html and /api/v1/swagger.json

  • Allow unauthenticated access to all other resources

For clarification on why your configuration doesn't work, it's because you're not reading spring-security like you should be reading it.

Your old configuration reads like this:

.authorizeRequests() // allow requests
    .antMatchers(...) // that matches this
        .hasAuthority("SWAGGER") // with SWAGGER authority
    .anyRequest() // All requests above
        .permitAll() // grant full access 

In other words, you're granting full access to users with the SWAGGER authority, but what you've neglected is that by default, they already have access to it. To be more precise, everybody has access to it unless you specify otherwise.

By using .authenticated(). you're telling Spring that you want all requests matched to be restricted to people with the proper role or authority.

New configuration:

.authorizeRequests() // allow requests
    .antMatchers(...) // that matches this
        .hasRole("SWAGGER") // with role SWAGGER
    .anyRequest() // all requests above
        .authenticated() // needs authentication

Update

Regarding your issue with /swagger-resources, /swagger-resources/configuration/security and swagger-resources/configuration/ui returning 401:

You should replace /swagger-resources/* for /swagger-resources/**.

Update 2

Add the following at the end of your configuration to permit all non-matched requests:

.authorizeRequests()
    .anyRequest()
        .permitAll();