【问题标题】:Enabling Swagger springdoc-openapi-ui (OpenAPI 3.0) with Spring Security - Cannot access swagger-ui.html (401)使用 Spring Security 启用 Swagger springdoc-openapi-ui (OpenAPI 3.0) - 无法访问 swagger-ui.html (401)
【发布时间】:2021-06-03 22:41:38
【问题描述】:

Swagger OpenAPI 3.0 正在使用 springdoc-openapi-ui 和自定义 OpenAPI Bean。

pom.xml

<parent>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-parent</artifactId>
  <version>Hoxton.SR10</version>
</parent>
...
<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.5.5</version>
</dependency>

Swagger 配置:

spring-security 配置相同的问题

在使用 springdoc-openapi-ui、springdoc-openapi-security 以及 spring-boot-starter-security 和 keycloak-spring-boot-starter 时,我们遇到了一个问题。

pom.xml

<dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-security</artifactId>
      <version>1.5.5</version>
</dependency>
<dependency>
      <groupId>org.keycloak</groupId>
      <artifactId>keycloak-spring-boot-starter</artifactId>
      <version>12.0.2</version>
</dependency>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
      <version>2.4.2</version>
</dependency>

DummySecurityConfig(目前使用profile dev):

@Profile({"test", "dev"})
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        prePostEnabled = true,
        securedEnabled = true,
        jsr250Enabled = true)
@EnableWebMvc
public class DummySecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {

    protected static final String[] ACTUATOR_WHITELIST = {
        "/actuator/**"
    };

    protected static final String[] SWAGGER_WHITELIST = {
        "/v3/api-docs/**",
        "/swagger-ui/**",
        "/swagger-ui.html",
    };

    @Value("${client.cors.allowed-origins:*}")
    private String[] allowedOrigins;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
            .anyRequest().authenticated()
            .and()
            .httpBasic(); //or anything else, e.g. .oauth2ResourceServer().jwt()
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());
    }


    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
                .antMatchers(SWAGGER_WHITELIST)
                .antMatchers(ACTUATOR_WHITELIST);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins(allowedOrigins);
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        AuthenticationProvider authenticationProvider = new AuthenticationProvider() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + authentication.getPrincipal().toString().toUpperCase());

                UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                        authentication.getPrincipal(), authentication.getCredentials(), Collections.singleton(authority));
                token.setDetails(authentication);
                return token;
            }

            @Override
            public boolean supports(Class<?> aClass) {
                return true;
            }
        };

        return authenticationProvider;
    }
}

SecurityConfig(示例中未使用,但将来也会使用):

@Profile({"staging", "devstaging"})
@KeycloakConfiguration
@EnableGlobalMethodSecurity(
    prePostEnabled = true,
    securedEnabled = true,
    jsr250Enabled = true)
@EnableWebMvc
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter implements WebMvcConfigurer {

    protected static final String[] ACTUATOR_WHITELIST = {
        "/actuator/**"
    };

    protected static final String[] SWAGGER_WHITELIST = {
        "/v3/api-docs/**",
        "/swagger-ui/**",
        "/swagger-ui.html",
    };

    @Value("${client.cors.allowed-origins:*}")
    private String[] allowedOrigins;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
        grantedAuthorityMapper.setConvertToUpperCase(true);
        grantedAuthorityMapper.setPrefix("ROLE_");

        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
            .antMatchers(SWAGGER_WHITELIST)
            .antMatchers(ACTUATOR_WHITELIST);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
            .csrf().disable()
            .cors().and()
            .authorizeRequests().anyRequest().authenticated();
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins(allowedOrigins);
    }
}

应用程序-dev.yml:

server:
  port: 8083
  servlet:
    context-path: /planning
keycloak:
  enabled: false
springdoc:
  show-actuator: true

我们已经尝试使用以下链接来解决问题:

打开 swagger-ui URL 的示例(配置文件开发):

http://localhost:8083/planning/swagger-ui.html(不起作用):

应用代码sn-p:

2021-03-05 09:27:01,530 [http-nio-8083-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/planning] threw exception [Could not resolve view with name 'redirect:/swagger-ui/index.html?configUrl=/planning/v3/api-docs/swagger-config' in servlet with name 'dispatcherServlet'] with root cause
javax.servlet.ServletException: Could not resolve view with name 'redirect:/swagger-ui/index.html?configUrl=/planning/v3/api-docs/swagger-config' in servlet with name 'dispatcherServlet'
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1138)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1077)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)

http://localhost:8083/planning/swagger-ui/index.html?configUrl=/planning/v3/api-docs/swagger-config(有效但很复杂):

http://localhost:8083/planning/swagger-ui/index.html(手动添加 api-docs "/planning/v3/api-docs" 也可以):

您有什么想法还有什么可能是错误的配置或我们应该改变什么?我们的拉丁文已经结束了。

【问题讨论】:

    标签: java spring-security openapi user-roles springdoc


    【解决方案1】:

    正如日志所说,Could not resolve view with name 'redirect:/swagger-ui/index.html?configUrl=**/planning/v3/api-docs/swagger-config'**。 在您的网络安全配置中,您只能访问 /v3/api-docs/。 尝试添加/planning/或修改路径。

    【讨论】:

    • 感谢@user15400529 的回答和您的提示,但不幸的是它不起作用。 1. 我将 /planning/ 添加到 SWAGGER_WHITELIST 并配置(HttpSecurity http) {http.authorizeRequests().antMatchers("/v3/api-docs/**", "/ Planning/", "/swagger-ui/**", "/swagger-ui.html").permitAll().} 仍然出现 401 状态码。 2.我尝试适配springdoc.swagger-ui.configUrl属性,并将值设置为/v3/api-docs/swagger-config。但是,我认为上下文路径(例如 /planning 在我的例子中)已经被用作所有 URL 属性的前缀。
    • 在这两种情况下相同的异常 无法解析名称为“redirect:/swagger-ui/index.html?configUrl=/planning/v3/api-docs/swagger-config”的视图在名称为“dispatcherServlet” 的 servlet 中出现。你知道解决这个问题的任何其他方法/配置吗?
    猜你喜欢
    • 2020-05-10
    • 2020-12-18
    • 2020-09-09
    • 1970-01-01
    • 2022-10-25
    • 2021-05-07
    • 2021-02-25
    • 1970-01-01
    • 2021-11-14
    相关资源
    最近更新 更多