一个非常具体的 Spring Boot 执行器/swagger 集成问题

问题描述 投票:0回答:1

我正在启动我的 springboot web 应用程序并导航到 localhost/api/myservice/swagger-ui/index.html,但收到 401 Unauthorized。从现在起,我已经做了所有常见的事情,有无数的答案,但似乎没有一个专门适用于 spring 和 spring 文档的这对配对。我的一个限制是 Java 1.8,否则我会使用更新版本的软件。手铐。

简短版本: 弹簧启动:2.7.18 弹簧文档:1.8.0

pom.xml 片段:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
    </parent>

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

当我检查时,springdocs 的 springboot 的最旧版本已经超过了 Java 1.8。

application.yml 片段:

springdoc:
  api-docs:
    path: /api-docs/**
  swagger-ui:
    enabled = true
    path = /swagger-ui.html
    tryItOutEnabled = false
    filter = false
    syntaxHighlight.activated = true
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
server:
  servlet:
    context-path: /api/myservice

SwaggerConfig.java 片段:

@Configuration
public class SwaggerConfig {
    @Bean
    public GroupedOpenApi api() {
        return GroupedOpenApi.builder()
                .group("us/cargosphere/**")
                .pathsToMatch("/**")
                .packagesToExclude("/error.**")
                .build();
    }

    @Bean
    public OpenAPI apiInfo() {
        final String securitySchemeName = "bearerAuth";
        return new OpenAPI()
                .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
                .components(new Components().addSecuritySchemes(
                        securitySchemeName,
                        new SecurityScheme()
                                .name(securitySchemeName)
                                .type(SecurityScheme.Type.HTTP)
                                .in(SecurityScheme.In.HEADER)
                                .scheme("bearer")
                                .bearerFormat("JWT")
                ))
                .info(new Info()
                        .title(title)
                        .version(version)
                        .description("")
                )
                .servers(Collections.singletonList(
                        new Server()
                                .url(contextPath)
                                .description("Default Server URL")
                ));
    }
}

SpringConfiguration.java 片段:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringConfiguration {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// I have tried very many things here, but I don't see how it could get much more permissive than this ;)
        http
                .csrf().disable()
                .authorizeRequests().anyRequest().permitAll();
        return http
                .build();
    }

    @Bean
    public RequestMatcher requestMatcher() {
        this.log.debug("Creating request matcher");
        List<RequestMatcher> requestMatchers = new ArrayList<>();
        requestMatchers.add(new AntPathRequestMatcher("/**"));
        return new OrRequestMatcher(requestMatchers);
    }

    @Bean
    public CustomAuthenticationFilter customAuthenticationFilter(
            RequestMatcher requestMatcher,
            AuthenticationConfiguration authenticationConfiguration)
            throws Exception {
        CustomAuthenticationFilter result = new CustomAuthenticationFilter(requestMatcher);
        result.setAuthenticationManager(authenticationConfiguration.getAuthenticationManager());
        return result;
    }

}

当我取消注释 CustomAuthenticationFilter 内容时,我得到 401 Unauthorized 访问 localhost/api/myservice/swagger-ui/index.html,因为正在应用该类,但是当我将其注释掉时,我就可以正常访问 swagger 页面了。

我是这个版本的 SpringBoot 的新手,也是 Swagger 3 的新手,也是 springdocs 的新手。我在其他使用 FilterRegistrationBean 而不是 CustomAuthenticationFilter 的微服务中使用了此功能,并且我不确定为什么相同的配置在此存储库中不起作用。如果可以在不禁用 csrf 的情况下完成此操作,则可获得奖励积分。

当我导航到 localhost/api/myservice/swagger-ui/index.html 时,我收到 401 Unauthorized。我希望 Swagger 页面无需授权即可加载。

当我注释掉 CustomAuthenticationFilter bean 时,我得到了预期的结果。除了确定 CustomAuthenticationFilter 被用于保护 Swagger 页面(当我不希望这样做时)之外,我不知道为什么。

我也尝试过

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer(@Value("${server.servlet.context-path}") String contextPath) {
        return web -> web
                .ignoring()
                .antMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", contextPath + "/swagger-ui/**");
    }

它会在控制台上发出有关使用authorizeHttpRequests 的打印警告。我也尝试过。

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                //.authorizeHttpRequests()
                .antMatchers(
                        "/v2/api-docs",
                        "/v3/api-docs/**",
                        "/swagger-resources/**",
                        "/swagger-ui/**",
                        "/swagger-ui.html",
                        "/swagger-ui/index.html",
                        contextPath + "/swagger-ui/index.html",
                        "/configuration/ui",
                        "/configuration/security",
                        "/webjars/**",
                        "/api/**",
                        contextPath + "/swagger-ui/**"
                ).permitAll()
                .and().authorizeRequests().antMatchers("/api/**").authenticated();
        return http.build();
    }
java springdoc springdoc-openapi-ui swagger-3.0 spring-boot-security
1个回答
0
投票

您要做的第一件事就是从安全上下文(SecurityFilterChain)中排除 swagger 端点,您已经在 WebSecurityCustomizer 中完成了配置,无需再次执行。

你需要的是:

  @Bean
  public WebSecurityCustomizer webSecurityCustomizer() {
  return (web) ->
    web.ignoring()
        .requestMatchers(
            new AntPathRequestMatcher("/user/**"),
                new AntPathRequestMatcher("/v3/api-docs/**"),
                new AntPathRequestMatcher("/swagger-ui/**"),
                new AntPathRequestMatcher("/swagger-ui.html")
        )
  ; 
  }

application.properties(你可以将其更改为yml):

springdoc.api-docs.enabled=true
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.swagger-ui.enabled=true
springdoc.swagger-ui.operationsSorter=method
springdoc.swagger-ui.tryItOutEnabled=true
springdoc.swagger-ui.filter=true
springdoc.swagger-ui.tagsSorter=alpha
springdoc.api-docs.path=/v3/api-docs

最后你可以保持 OpenAPI() 不变,或者:

    @OpenAPIDefinition(
        info = @Info(
                contact = @Contact(
                        name = ""
                ),
                description = "",
                title = "",
                version = "",
                license = @License(
                        name = "",
                        url = ""
                ),
                termsOfService = "Terms of service"
        ),
        servers = {
                @Server(
                        description = "Local ENV",
                        url = ""
                ),
                @Server(
                        description = "PROD ENV",
                        url = ""
                ),
                @Server(
                        description = "TEST ENV",
                        url = ""
                )
        },
        security = {
                @SecurityRequirement(
                        name = "bearerAuth"
                )
        }
)
@SecurityScheme(
        name = "bearerAuth",
        description = "JWT auth description",
        scheme = "bearer",
        type = SecuritySchemeType.HTTP,
        bearerFormat = "JWT",
        in = SecuritySchemeIn.HEADER
)

@Configuration
public class SwaggerConfig {

 @Bean
public GroupedOpenApi api() {
    return GroupedOpenApi.builder()
            .group("us/cargosphere/**")
            .pathsToMatch("/**")
            .packagesToExclude("/error.**")
            .build();
}

}

© www.soinside.com 2019 - 2024. All rights reserved.