How to configure Spring Security to allow Swagger URL to be accessed without authentication

198,405

Solution 1

Adding this to your WebSecurityConfiguration class should do the trick.

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs",
                                   "/configuration/ui",
                                   "/swagger-resources/**",
                                   "/configuration/security",
                                   "/swagger-ui.html",
                                   "/webjars/**");
    }

}

Solution 2

I had the same problem using Spring Boot 2.0.0.M7 + Spring Security + Springfox 2.8.0. And I solved the problem using the following security configuration that allows public access to Swagger UI resources.

Answer updated in January 2021 : support Springfox 3

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final String[] AUTH_WHITELIST = {
            // -- Swagger UI v2
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**",
            // -- Swagger UI v3 (OpenAPI)
            "/v3/api-docs/**",
            "/swagger-ui/**"
            // other public endpoints of your API may be appended to this array
    };


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                // ... here goes your custom security configuration
                authorizeRequests().
                antMatchers(AUTH_WHITELIST).permitAll().  // whitelist Swagger UI resources
                // ... here goes your custom security configuration
                antMatchers("/**").authenticated();  // require authentication for any endpoint that's not whitelisted
    }

}

Solution 3

I updated with /configuration/** and /swagger-resources/** and it worked for me.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/**", "/swagger-ui.html", "/webjars/**");

}

Solution 4

For those who using a newer swagger 3 version org.springdoc:springdoc-openapi-ui

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**");
    }
}

Solution 5

if your springfox version higher than 2.5, should be add WebSecurityConfiguration as below:

@Override
public void configure(HttpSecurity http) throws Exception {
    // TODO Auto-generated method stub
    http.authorizeRequests()
        .antMatchers("/v2/api-docs", "/swagger-resources/configuration/ui", "/swagger-resources", "/swagger-resources/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .csrf().disable();
}
Share:
198,405

Related videos on Youtube

shubhendu_shekhar
Author by

shubhendu_shekhar

BY DAY : Senior Developer at Mu Sigma Inc. BY NIGHT : Binge watching TV Shows and movies. Identifiable traits : Introvert, Intelligent, Humorist, Tech Addict Trying to be the best at most of the things I do

Updated on July 08, 2022

Comments

  • shubhendu_shekhar
    shubhendu_shekhar almost 2 years

    My project has Spring Security. Main issue: Not able to access swagger URL at http://localhost:8080/api/v2/api-docs. It says Missing or invalid Authorization header.

    Screenshot of the browser window My pom.xml has the following entries

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.4.0</version>
    </dependency>
    
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.4.0</version>
    </dependency>
    

    SwaggerConfig :

    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
    
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2).select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo());
    }
    
    private ApiInfo apiInfo() {
        ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", "[email protected]", "License of API", "API license URL");
        return apiInfo;
    }
    

    AppConfig:

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = { "com.musigma.esp2" })
    @Import(SwaggerConfig.class)
    public class AppConfig extends WebMvcConfigurerAdapter {
    
    // ========= Overrides ===========
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
    }
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
          .addResourceLocations("classpath:/META-INF/resources/");
    
        registry.addResourceHandler("/webjars/**")
          .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    

    web.xml entries:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            com.musigma.esp2.configuration.AppConfig
            com.musigma.esp2.configuration.WebSecurityConfiguration
            com.musigma.esp2.configuration.PersistenceConfig
            com.musigma.esp2.configuration.ACLConfig
            com.musigma.esp2.configuration.SwaggerConfig
        </param-value>
    </context-param>
    

    WebSecurityConfig:

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @ComponentScan(basePackages = { "com.musigma.esp2.service", "com.musigma.esp2.security" })
    public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
            .csrf()
                .disable()
            .exceptionHandling()
                .authenticationEntryPoint(this.unauthorizedHandler)
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            .authorizeRequests()
                .antMatchers("/auth/login", "/auth/logout").permitAll()
                .antMatchers("/api/**").authenticated()
                .anyRequest().authenticated();
    
            // custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication
            httpSecurity.addFilterBefore(loginFilter(), UsernamePasswordAuthenticationFilter.class);
    
            // custom Token based authentication based on the header previously given to the client
            httpSecurity.addFilterBefore(new StatelessTokenAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class);
        }
    }
    
  • Daniel Martín
    Daniel Martín over 7 years
    If you use swagger-ui you need something like this: .antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**","/swagger-resources/configuration/ui","/swagge‌​r-ui.html").permitAl‌​l()
  • nikolai.serdiuk
    nikolai.serdiuk about 7 years
    In my case this rule is working: .antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**", "/swagger-resources/configuration/ui", "/swagge‌​r-ui.html", "/swagger-resources/configuration/security").permitAll()
  • Chandrakant Audhutwar
    Chandrakant Audhutwar about 6 years
    after adding this class, I'm able to see swagger-ui but APIs are not accessed via postman even with access_token, getting access forbidden error as below, { "timestamp": 1519798917075, "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/<some path>/shop" }
  • naXa stands with Ukraine
    naXa stands with Ukraine about 6 years
    @ChandrakantAudhutwar delete antMatchers("/**").authenticated() statement or replace with your own authentication configuration. Be careful, you better know what you're doing with security.
  • Chandrakant Audhutwar
    Chandrakant Audhutwar about 6 years
    yes, it worked. I was thinking of only bypassing swagger-ui, but other APIs as it is secured. now my APIs are also bypassed.
  • naXa stands with Ukraine
    naXa stands with Ukraine about 6 years
    @ChandrakantAudhutwar you do not need to copy-paste the whole SecurityConfiguration class to your project. You should have your own SecurityConfiguration where you permit requests to Swagger UI resources and keep your APIs secure.
  • Chandrakant Audhutwar
    Chandrakant Audhutwar about 6 years
    I have AuthorizationServerConfigurerAdapter implemented class which makes API' authentication.
  • GSUgambit
    GSUgambit about 6 years
    @ChandrakantAudhutwar care to explain how you got around your issue? I can access my swagger page as well but when i hit "Try it" the response body is the login page so it's being redirected
  • GSUgambit
    GSUgambit about 6 years
    @ChandrakantAudhutwar it's as if I need to find a way to give swagger a security role so it's not anonymous i see this in my logs: o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpres‌​sionVoter@1afeff6, returned: -1 o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
  • Toby Speight
    Toby Speight about 6 years
    Thank you for this code snippet, which might provide some limited short-term help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
  • Mate Šimović
    Mate Šimović almost 6 years
    Needed more rules: .antMatchers("/", "/csrf", "/v2/api-docs", "/swagger-resources/configuration/ui", "/configuration/ui", "/swagger-resources", "/swagger-resources/configuration/security", "/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()
  • Mahieddine M. Ichir
    Mahieddine M. Ichir over 5 years
    duliu1990 is right, since springfox 2.5+, all the springfox resources (swagger included) have moved under /swagger-resources. /v2/api-docs is the default swagger api endpoint (of no concern with the UI), which can be overridden with the config variable springfox.documentation.swagger.v2.path springfox
  • ssimm
    ssimm over 5 years
    Thanks for the answer! Is there any security risk allowing access to webjars/** ?
  • Vishal
    Vishal almost 5 years
    Why are you adding /csrf in exclusion?
  • Madhu
    Madhu almost 5 years
    Perfect! Solved the issue.
  • Vinícius M
    Vinícius M almost 4 years
    Note: If this stops you from getting a "Authentication Required" error, but just shows you a blank page, I also had to add "/swagger-resources/**" and "/swagger-resources" in that list and it fixed it for me.
  • Praveenkumar Beedanal
    Praveenkumar Beedanal over 3 years
    very helpful answer
  • FourtyTwo
    FourtyTwo over 3 years
    I had to add .., "/swagger-ui/**"... to that list
  • Fabio Cardoso
    Fabio Cardoso over 3 years
    I know this answer is old, but if you add "/swagger-ui/**" to the list, it will be perfect. Springfox 3.0.0 URL is that way.
  • Fabio Cardoso
    Fabio Cardoso over 3 years
    @FourtyTwo me too, that's because Springfox 3.0.0 was changed the path.
  • Joey
    Joey over 2 years
    This list absolutely didn't work for me.
  • Ondra K.
    Ondra K. over 2 years
    Could you please add a description of the individual endpoints, why they need to be permitted? I have permitted only /webjars/swagger-ui/**, swagger-ui.html and /v3/api-docs/** and everything seems to be working so far, but perhaps there's some swagger functionality that I overlooked? Or are the configuration endpoints only for springfox?
  • SPS
    SPS over 2 years
    for me .authorizeRequests().antMatchers("/v2/api-docs", "/swagger-resources/**", "/swagger-ui/**").permitAll().and() was sufficient
  • SPS
    SPS over 2 years
    for me .authorizeRequests().antMatchers("/v2/api-docs", "/swagger-resources/**", "/swagger-ui/**").permitAll().and() was sufficient
  • Aaron
    Aaron about 2 years
    Thanks for posting this; just helped me with Swagger v3.
  • Armer B.
    Armer B. about 2 years
    I've tested on v3 and can say this configuration works, but if into requests you need Principal, for example to extract username, then Swagger anyway fails, so I avoid spring boot open api.