| | |
| | | package com.ruoyi.web.core.config; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import com.ruoyi.common.config.RuoYiConfig; |
| | | import io.swagger.v3.oas.models.Components; |
| | | import io.swagger.v3.oas.models.OpenAPI; |
| | | import io.swagger.v3.oas.models.info.Contact; |
| | | import io.swagger.v3.oas.models.info.Info; |
| | | import io.swagger.v3.oas.models.info.License; |
| | | import io.swagger.v3.oas.models.media.StringSchema; |
| | | import io.swagger.v3.oas.models.parameters.Parameter; |
| | | import io.swagger.v3.oas.models.security.SecurityRequirement; |
| | | import io.swagger.v3.oas.models.security.SecurityScheme; |
| | | import io.swagger.v3.oas.models.security.SecurityScheme.In; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Optional; |
| | | import org.springdoc.core.customizers.OpenApiBuilderCustomizer; |
| | | import org.springdoc.core.customizers.ServerBaseUrlCustomizer; |
| | | import org.springdoc.core.models.GroupedOpenApi; |
| | | import org.springdoc.core.properties.SpringDocConfigProperties; |
| | | import org.springdoc.core.providers.JavadocProvider; |
| | | import org.springdoc.core.service.OpenAPIService; |
| | | import org.springdoc.core.service.SecurityService; |
| | | import org.springdoc.core.utils.PropertyResolverUtils; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.http.HttpHeaders; |
| | | |
| | | /** |
| | | * Swagger2çæ¥å£é
ç½® |
| | | * Swagger èªå¨é
置类ï¼åºäº OpenAPI + Springdoc å®ç°ã |
| | | * |
| | | * @author ruoyi |
| | | * åæ
æç¤ºï¼ |
| | | * 1. Springdoc ææ¡£å°åï¼<a href="https://github.com/springdoc/springdoc-openapi">ä»åº</a> |
| | | * 2. Swagger è§èï¼äº 2015 æ´å为 OpenAPI è§èï¼æ¬è´¨æ¯ä¸ä¸ªä¸è¥¿ |
| | | * |
| | | */ |
| | | // @AutoConfiguration |
| | | @Configuration |
| | | @ConditionalOnClass({OpenAPI.class}) |
| | | @EnableConfigurationProperties(SwaggerProperties.class) |
| | | @ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true) // 设置为 false æ¶ï¼ç¦ç¨ |
| | | public class SwaggerConfig |
| | | { |
| | | /** ç³»ç»åºç¡é
ç½® */ |
| | | @Autowired |
| | | private RuoYiConfig ruoyiConfig; |
| | | |
| | | /** |
| | | * èªå®ä¹ç OpenAPI 对象 |
| | | */ |
| | | @Bean |
| | | public OpenAPI customOpenApi() |
| | | { |
| | | return new OpenAPI().components(new Components() |
| | | // 设置认è¯ç请æ±å¤´ |
| | | .addSecuritySchemes("apikey", securityScheme())) |
| | | .addSecurityItem(new SecurityRequirement().addList("apikey")) |
| | | .info(getApiInfo()); |
| | | } |
| | | public static final String HEADER_TENANT_ID = "tenant-id"; |
| | | |
| | | |
| | | // ========== å
¨å± OpenAPI é
ç½® ========== |
| | | |
| | | @Bean |
| | | public SecurityScheme securityScheme() |
| | | { |
| | | return new SecurityScheme() |
| | | .type(SecurityScheme.Type.APIKEY) |
| | | .name("Authorization") |
| | | .in(SecurityScheme.In.HEADER) |
| | | .scheme("Bearer"); |
| | | public OpenAPI createApi(SwaggerProperties properties) { |
| | | Map<String, SecurityScheme> securitySchemas = buildSecuritySchemes(); |
| | | OpenAPI openAPI = new OpenAPI() |
| | | // æ¥å£ä¿¡æ¯ |
| | | .info(buildInfo(properties)) |
| | | // æ¥å£å®å
¨é
ç½® |
| | | .components(new Components().securitySchemes(securitySchemas)) |
| | | .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); |
| | | securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); |
| | | return openAPI; |
| | | } |
| | | |
| | | /** |
| | | * æ·»å æè¦ä¿¡æ¯ |
| | | * API æè¦ä¿¡æ¯ |
| | | */ |
| | | public Info getApiInfo() |
| | | { |
| | | private Info buildInfo(SwaggerProperties properties) { |
| | | return new Info() |
| | | // 设置æ é¢ |
| | | .title("æ é¢ï¼è¥ä¾ç®¡çç³»ç»_æ¥å£ææ¡£") |
| | | // æè¿° |
| | | .description("æè¿°ï¼ç¨äºç®¡çé墿ä¸å
¬å¸ç人åä¿¡æ¯,å
·ä½å
æ¬XXX,XXX模å...") |
| | | // ä½è
ä¿¡æ¯ |
| | | .contact(new Contact().name(ruoyiConfig.getName())) |
| | | // çæ¬ |
| | | .version("çæ¬å·:" + ruoyiConfig.getVersion()); |
| | | .title(properties.getTitle()) |
| | | .description(properties.getDescription()) |
| | | .version(properties.getVersion()) |
| | | .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail())) |
| | | .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl())); |
| | | } |
| | | |
| | | /** |
| | | * å®å
¨æ¨¡å¼ï¼è¿éé
ç½®éè¿è¯·æ±å¤´ Authorization ä¼ é token åæ° |
| | | */ |
| | | private Map<String, SecurityScheme> buildSecuritySchemes() { |
| | | Map<String, SecurityScheme> securitySchemes = new HashMap<>(); |
| | | SecurityScheme securityScheme = new SecurityScheme() |
| | | .type(SecurityScheme.Type.APIKEY) // ç±»å |
| | | .name(HttpHeaders.AUTHORIZATION) // 请æ±å¤´ç name |
| | | .in(SecurityScheme.In.HEADER); // token æå¨ä½ç½® |
| | | securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme); |
| | | return securitySchemes; |
| | | } |
| | | |
| | | /** |
| | | * èªå®ä¹ OpenAPI å¤çå¨ |
| | | */ |
| | | @Bean |
| | | public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI, |
| | | SecurityService securityParser, |
| | | SpringDocConfigProperties springDocConfigProperties, |
| | | PropertyResolverUtils propertyResolverUtils, |
| | | Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers, |
| | | Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers, |
| | | Optional<JavadocProvider> javadocProvider) { |
| | | |
| | | return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, |
| | | propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider); |
| | | } |
| | | |
| | | // ========== åç» OpenAPI é
ç½® ========== |
| | | |
| | | /** |
| | | * æææ¨¡åç API åç» |
| | | */ |
| | | @Bean |
| | | public GroupedOpenApi allGroupedOpenApi() { |
| | | return buildGroupedOpenApi("all", ""); |
| | | } |
| | | |
| | | public static GroupedOpenApi buildGroupedOpenApi(String group) { |
| | | return buildGroupedOpenApi(group, group); |
| | | } |
| | | |
| | | public static GroupedOpenApi buildGroupedOpenApi(String group, String path) { |
| | | return GroupedOpenApi.builder() |
| | | .group(group) |
| | | .pathsToMatch("/admin-api/" + path + "/**", "/app-api/" + path + "/**", "/**") |
| | | .addOperationCustomizer((operation, handlerMethod) -> operation |
| | | // .addParametersItem(buildTenantHeaderParameter()) |
| | | .addParametersItem(buildSecurityHeaderParameter())) |
| | | .build(); |
| | | } |
| | | |
| | | /** |
| | | * æå»º Authorization 认è¯è¯·æ±å¤´åæ° |
| | | * |
| | | * è§£å³ Knife4j <a href="https://gitee.com/xiaoym/knife4j/issues/I69QBU">Authorize æªçæï¼è¯·æ±headeréæªå
å«åæ°</a> |
| | | * |
| | | * @return 认è¯åæ° |
| | | */ |
| | | private static Parameter buildSecurityHeaderParameter() { |
| | | return new Parameter() |
| | | .name(HttpHeaders.AUTHORIZATION) // header å |
| | | .description("è®¤è¯ Token") // æè¿° |
| | | .in(String.valueOf(SecurityScheme.In.HEADER)) // è¯·æ± header |
| | | .schema(new StringSchema()._default("Bearer test1").name(HEADER_TENANT_ID).description("è®¤è¯ Token")); // é»è®¤ï¼ä½¿ç¨ç¨æ·ç¼å·ä¸º 1 |
| | | } |
| | | |
| | | /** |
| | | * æå»º Tenant ç§æ·ç¼å·è¯·æ±å¤´åæ° |
| | | * @return å¤ç§æ·åæ° |
| | | */ |
| | | /* private static Parameter buildTenantHeaderParameter() { |
| | | return new Parameter() |
| | | .name(HEADER_TENANT_ID) // header å |
| | | .description("ç§æ·ç¼å·") // æè¿° |
| | | .in(String.valueOf(SecurityScheme.In.HEADER)) // è¯·æ± header |
| | | .schema(new IntegerSchema()._default(1L).name(HEADER_TENANT_ID).description("ç§æ·ç¼å·")); // é»è®¤ï¼ä½¿ç¨ç§æ·ç¼å·ä¸º 1 |
| | | } */ |
| | | } |