Search code examples
javaspringspring-securityswaggerswagger-ui

Swagger-ui with Spring security


I have a simple REST application with authentication service. I tried to add swagger and swagger-ui to it, but I can only see my endpoints in /v2/api-docs. In swagger-ui.html I see only groups of endpoints but I am unable to extend any list.

In chrome debug I see:

Failed to load resource: the server responded with a status of 401 ()

Uncaught TypeError: Cannot read property 'indexOf' of undefined

and on a terminal with a server:

ERROR 10020 --- [nio-5001-exec-3] c.t.r.a.p.JwtAuthenticationEntryPoint : Responding with unauthorized error. Message - Full authentication is required to access this resource

It looks like my config files are missing something, I tried few solutions I found on a web but still nothing work.

This is my code:

pom

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

controller

@RestController
@PreAuthorize("hasRole('USER')")
@RequestMapping(path = "restaurant")
@Api(value="restaurant", description="Example operations for restaurants")
public class RestaurantController {
// endpoints
}

swagger bean

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.tablebooker.restaurantservice.restaurant"))
                .paths(PathSelectors.any())
                .build();
    }
}

SecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        securedEnabled = true,
        jsr250Enabled = true,
        prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//other methods

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/",
                        "/favicon.ico",
                        "/**/*.png",
                        "/**/*.gif",
                        "/**/*.svg",
                        "/**/*.jpg",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js")
                .permitAll()
                .antMatchers("/api/auth/**")
                .permitAll()
                .antMatchers("/restaurant/**")
                .hasRole("USER")
                .anyRequest()
                .authenticated();

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

    }

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

Any ideas how can I make my configuration work?


Solution

  • First you should registry swagger's resources.

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("swagger-ui.html")
                    .addResourceLocations("classpath:/META-INF/resources/");
        }
    }
    

    Then cause you're using Spring Security,maybe you should shutdown privileges.

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

    And maybe it's better for you to use swagger which the version is under 2.8.0,or you may have to face to lots of bugs.