如何在加载外部OpenAPI的Swagger UI中启用Authorize按钮
我有一个从其他位置获取OpenAPI的服务器,想在Swagger UI中启用Authorize按钮,仅需实现将JWT作为Authorization请求头传递的功能。
以下是最小可复现示例(MRE):Stapi本身是完全开放的,但可以将其视为某个微服务,Swagger UI服务器作为网关(实际场景正是如此)。另外注意,Stapi的OpenAPI文档已过时,无法实际调用任何端点。
我接受修改提供API文档的服务器源码的建议(我拥有实际微服务的写入权限)。
代码实现
主启动类
package com.example.gatewaydemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GatewaydemoApplication { public static void main(String[] args) { SpringApplication.run(GatewaydemoApplication.class, args); } }
ApiProvider接口
package com.example.gatewaydemo.service; import io.swagger.v3.oas.models.OpenAPI; import reactor.core.publisher.Mono; public interface ApiProvider { String getApiName(); Mono<OpenAPI> getOpenApi(); }
ApiProvider配置类
package com.example.gatewaydemo.config; import com.example.gatewaydemo.service.ApiProvider; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.parser.OpenAPIV3Parser; import io.swagger.v3.parser.core.models.SwaggerParseResult; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @Configuration public class ApiProviderConfig { @Bean public WebClient webClient() { int size = 16 * 1024 * 1024; ExchangeStrategies strategies = ExchangeStrategies.builder() .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(size)) .build(); return WebClient.builder() .exchangeStrategies(strategies) .build(); } @Bean public OpenAPIV3Parser openApiParser() { return new OpenAPIV3Parser(); } @Bean public ApiProvider stapiApiProvider(WebClient webClient, OpenAPIV3Parser parser) { return new ApiProvider() { @Override public String getApiName() { return "stapi"; } @Override public Mono<OpenAPI> getOpenApi() { return webClient.get() .uri("https://stapi.co/api/v1/rest/common/download/stapi.yaml") .retrieve() .bodyToMono(String.class) .map(parser::readContents) .map(SwaggerParseResult::getOpenAPI); } }; } }
ObjectMapper配置类
package com.example.gatewaydemo.config; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ObjectMapperConfig { @Bean public ObjectMapper nullIgnoringObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); return objectMapper; } }
SwaggerUI配置控制器
package com.example.gatewaydemo.controller; import com.example.gatewaydemo.model.SwaggerUiConfig; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController public class SwaggerUiConfigController { @GetMapping("/swagger-ui/config") public Mono<SwaggerUiConfig> getSwaggerUiConfig() { return Mono.just(SwaggerUiConfig.builder() .withConfigItemOf().url("/swagger-ui/doc/stapi").name("Star Trek API").build() .build()); } }
SwaggerUI文档控制器
package com.example.gatewaydemo.controller; import com.example.gatewaydemo.service.ApiProvider; import io.swagger.v3.oas.models.OpenAPI; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; import java.util.List; @RestController @RequiredArgsConstructor public class SwaggerUiDocController { private final List<ApiProvider> apiProviders; @GetMapping("/swagger-ui/doc/{api-name}") public Mono<OpenAPI> getOpenApi(@PathVariable("api-name") String apiName) { return apiProviders.stream() .filter(apiProvider -> apiProvider.getApiName().equals(apiName)) .findFirst() .orElseThrow() .getOpenApi(); } }
SwaggerUiConfig模型类
package com.example.gatewaydemo.model; import lombok.Getter; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @NoArgsConstructor @Getter public class SwaggerUiConfig { private final List<ConfigItem> urls = new ArrayList<>(); public SwaggerUiConfig(SwaggerUiConfigBuilder builder) { this.urls.addAll(builder.getUrls()); } public static SwaggerUiConfigBuilder builder() { return new SwaggerUiConfigBuilder(); } @Getter public static class SwaggerUiConfigBuilder { private final List<ConfigItem> urls = new ArrayList<>(); public ConfigItem.ConfigItemBuilder withConfigItemOf() { return new ConfigItem.ConfigItemBuilder(this); } public SwaggerUiConfig build() { return new SwaggerUiConfig(this); } } @NoArgsConstructor @Getter public static class ConfigItem { private String url; private String name; private ConfigItem(ConfigItemBuilder builder) { this.url = builder.getUrl(); this.name = builder.getName(); } @Getter public static class ConfigItemBuilder { private final SwaggerUiConfigBuilder configBuilderInstance; private String url; private String name; ConfigItemBuilder(SwaggerUiConfigBuilder configBuilderInstance) { this.configBuilderInstance = configBuilderInstance; } public ConfigItemBuilder url(String url) { this.url = url; return this; } public ConfigItemBuilder name(String name) { this.name = name; return this; } public SwaggerUiConfigBuilder build() { ConfigItem configItem = new ConfigItem(this); configBuilderInstance.urls.add(configItem); return configBuilderInstance; } } } }
Maven依赖配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>gatewaydemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>gatewaydemo</name> <description>gatewaydemo</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>io.swagger.parser.v3</groupId> <artifactId>swagger-parser</artifactId> <version>2.1.18</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webflux-ui</artifactId> <version>2.0.4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
Spring配置文件
springdoc: swagger-ui: config-url: /swagger-ui/config path: /swagger-ui
当前界面情况
访问http://localhost:8080/swagger-ui即可看到如下界面,缺少Authorize按钮,需要添加该按钮。

内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

