1

I have a problem about opening swagger ui in my Spring Boot Example.

I get this kind of error when I access to localhost:8080/swagger-ui or localhost:8080/root-api-name:swagger-ui

Securing GET /springboot-blog-rest-api/swagger-ui
2022-07-22 01:38:58.820 DEBUG 30576 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-07-22 01:38:58.820 DEBUG 30576 --- [nio-8080-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2022-07-22 01:38:58.820 DEBUG 30576 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor    : Failed to authorize filter invocation [GET /springboot-blog-rest-api/swagger-ui] with attributes [authenticated]
2022-07-22 01:38:58.820 DEBUG 30576 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-07-22 01:38:58.820 DEBUG 30576 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Securing GET /error
2022-07-22 01:38:58.821 DEBUG 30576 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-07-22 01:38:58.821 DEBUG 30576 --- [nio-8080-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2022-07-22 01:38:58.821 DEBUG 30576 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy        : Secured GET /error
2022-07-22 01:38:58.821 DEBUG 30576 --- [nio-8080-exec-4] a.DefaultWebInvocationPrivilegeEvaluator : filter invocation [/error] denied for AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]

org.springframework.security.access.AccessDeniedException: Access is denied

I used springfox-swagger2 version 3 , springfox-boot-starter version 3 and lastly springfox-swagger-ui version 2.9.

How can I fix my issue?

Here is my SwaggerConfig File.

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    public static final String AUTHORIZATION_HEADER = "Authorization";

    private ApiKey apiKey(){
        return new ApiKey("JWT", AUTHORIZATION_HEADER, "header");
    }

    private ApiInfo apiInfo(){
        return new ApiInfo(
                "Spring Boot Blog REST APIs",
                "Spring Boot Blog REST API Documentation",
                "1",
                "Terms of service",
                new Contact("Name", "website-address", "Email"),
                "License of API",
                "API license URL",
                Collections.emptyList()
        );
    }

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(apiKey()))
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    private SecurityContext securityContext(){
        return SecurityContext.builder().securityReferences(defaultAuth()).build();
    }

    private List<SecurityReference> defaultAuth(){
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Arrays.asList(new SecurityReference("JWT", authorizationScopes));
    }
}

Here is my SecurityConfig file

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {


    @Autowired
    private JwtAuthenticationEntryPoint authenticationEntryPoint;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter(){
        return  new JwtAuthenticationFilter();
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/v2/api-docs/**", 
                "/swagger-ui/**","/swagger-resources/**","/swagger-ui.html","/webjars/**");
    }

    @Bean
    protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        
        http
                .csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests((authorize) -> authorize
                        .antMatchers(HttpMethod.GET, "/api/v1/**").permitAll()
                        .antMatchers("/api/v1/auth/**").permitAll()
                        .anyRequest()
                        .authenticated()
                );
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    


}
5
  • it is interesting that permitAll() didn't work but i think you need to use ignoring() on wagger url. check out this post link Commented Jul 22, 2022 at 2:09
  • @pooya As you can see, I also used ignoring() but it didn't work. I also defined all these links regarding swagger securityFilterChain method but nothing changed. Commented Jul 22, 2022 at 9:25
  • i looked again on your code so i am thinking you should check first if you can set your configuration to ignore any URL from doing security process like create the test controller and see if it can get through the spring security. i said that because you didn't use public void configure(WebSecurity web) method for your configuration so if you find out your test controller can get through the spring security you must search how to exclude the URL by SecurityFilterChain . if your test controller couldn't get through the spring security you must change your method configuration and use Commented Jul 22, 2022 at 18:02
  • public void configure(WebSecurity web) Commented Jul 22, 2022 at 18:03
  • Please check my answer on How to run Swagger 3 on Spring Boot 3 Commented Mar 18, 2023 at 8:59

2 Answers 2

1

If you are using Spring Security, use the following security configuration to allow public access to Swagger UI resources:

public class SecurityConfig {

    private static final String[] AUTH_WHITELIST = {

            // for Swagger UI v2
            "/v2/api-docs",
            "/swagger-ui.html",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/webjars/**",

            // for Swagger UI v3 (OpenAPI)
            "/v3/api-docs/**",
            "/swagger-ui/**"
    };

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) {
        httpSecurity
                // ... other configuration settings                
                .antMatchers(AUTH_WHITELIST).permitAll();
        // ...
    }
}
Sign up to request clarification or add additional context in comments.

Comments

-2

Here is the answer

I can access the url through localhost:8080/swagger-ui.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.