From d7de40039b0bb2c553194d8c538174bdc64ed55f Mon Sep 17 00:00:00 2001 From: LarryKoo Date: Tue, 20 Mar 2018 22:53:03 +0800 Subject: [PATCH 1/4] =?UTF-8?q?1.=20=E6=96=B0=E5=A2=9E=E4=BA=86=20Swagger?= =?UTF-8?q?=20=E7=9A=84=20Authorization=20=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=BC=80=E5=A7=8B=20Api=20Key=20=E7=9A=84=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=EF=BC=9B=202.=20=E5=90=8C=E6=97=B6=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E6=A8=A1=E5=BC=8F=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87?= =?UTF-8?q?=20authRegex=20=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=8C=B9=E9=85=8D=E5=93=AA=E4=BA=9BURL?= =?UTF-8?q?=E4=BC=A0=E9=80=92=E6=8E=88=E6=9D=83=E4=BF=A1=E6=81=AF=EF=BC=9B?= =?UTF-8?q?=203.=20=E5=8D=87=E7=BA=A7=20Springfox-swagger=20=E5=88=B0=202.?= =?UTF-8?q?8.0=204.=20=E5=8D=87=E7=BA=A7=20lombok=20=E5=88=B0=201.16.18=20?= =?UTF-8?q?5.=20=E5=8D=87=E7=BA=A7spring-boot=E5=88=B0=201.5.9.RELEASE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 +- .../swagger/SwaggerAutoConfiguration.java | 82 +++++-- .../spring4all/swagger/SwaggerProperties.java | 229 ++++++++++++++---- 3 files changed, 242 insertions(+), 78 deletions(-) diff --git a/pom.xml b/pom.xml index 919934d..f3c96a8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.spring4all swagger-spring-boot-starter - 1.6.0.RELEASE + 1.6.1.RELEASE spring-boot-starter-swagger https://github.com/SpringForAll/spring-boot-starter-swagger @@ -48,8 +48,9 @@ UTF-8 1.8 - 2.7.0 - 1.5.6.RELEASE + 2.8.0 + 1.5.9.RELEASE + 1.16.18 @@ -81,7 +82,7 @@ org.projectlombok lombok - 1.16.12 + ${version.lombok} provided diff --git a/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java b/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java index c042126..2929252 100644 --- a/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java +++ b/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java @@ -2,7 +2,6 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; -import com.google.common.collect.Lists; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -17,17 +16,17 @@ import org.springframework.web.bind.annotation.RequestMethod; import springfox.documentation.builders.*; import springfox.documentation.schema.ModelRef; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.service.Parameter; -import springfox.documentation.service.ResponseMessage; +import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger.web.UiConfiguration; import java.util.*; import java.util.stream.Collectors; +import static com.google.common.collect.Lists.newArrayList; + /** * @author 翟永超 * Create date:2017/8/7. @@ -101,6 +100,8 @@ public List createRestApi(SwaggerProperties swaggerProperties) { Docket docketForBuilder = new Docket(DocumentationType.SWAGGER_2) .host(swaggerProperties.getHost()) .apiInfo(apiInfo) + .securitySchemes(this.securitySchemes()) + .securityContexts(this.securityContexts()) .globalOperationParameters(buildGlobalOperationParametersFromSwaggerProperties( swaggerProperties.getGlobalOperationParameters())); @@ -167,6 +168,8 @@ public List createRestApi(SwaggerProperties swaggerProperties) { Docket docketForBuilder = new Docket(DocumentationType.SWAGGER_2) .host(swaggerProperties.getHost()) .apiInfo(apiInfo) + .securitySchemes(this.securitySchemes()) + .securityContexts(this.securityContexts()) .globalOperationParameters(assemblyGlobalOperationParameters(swaggerProperties.getGlobalOperationParameters(), docketInfo.getGlobalOperationParameters())); @@ -197,6 +200,39 @@ public List createRestApi(SwaggerProperties swaggerProperties) { return docketList; } + /** + * 配置 Authorization ApiKey + * + * @return + */ + private List securitySchemes() { + return newArrayList( + new ApiKey(swaggerProperties().getAuthorization().getName(), + swaggerProperties().getAuthorization().getKeyName(), "header")); + } + + /** + * 通过正则设置需要传递 Authorization 信息的API接口 + * + * @return + */ + private List securityContexts() { + return newArrayList( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex())) + .build() + ); + } + + List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + return newArrayList( + new SecurityReference("BearerToken", authorizationScopes)); + } + @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { @@ -206,7 +242,7 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { private List buildGlobalOperationParametersFromSwaggerProperties( List globalOperationParameters) { - List parameters = Lists.newArrayList(); + List parameters = newArrayList(); if (Objects.isNull(globalOperationParameters)) { return parameters; @@ -242,7 +278,7 @@ private List assemblyGlobalOperationParameters( .map(SwaggerProperties.GlobalOperationParameter::getName) .collect(Collectors.toSet()); - List resultOperationParameters = Lists.newArrayList(); + List resultOperationParameters = newArrayList(); if (Objects.nonNull(globalOperationParameters)) { for (SwaggerProperties.GlobalOperationParameter parameter : globalOperationParameters) { @@ -268,24 +304,24 @@ private void buildGlobalResponseMessage(SwaggerProperties swaggerProperties, Doc swaggerProperties.getGlobalResponseMessage(); // POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE 响应消息体 - List postResponseMessages = getResponseMessageList(globalResponseMessages.getPost()); - List getResponseMessages = getResponseMessageList(globalResponseMessages.getGet()); - List putResponseMessages = getResponseMessageList(globalResponseMessages.getPut()); - List patchResponseMessages = getResponseMessageList(globalResponseMessages.getPatch()); - List deleteResponseMessages = getResponseMessageList(globalResponseMessages.getDelete()); - List headResponseMessages = getResponseMessageList(globalResponseMessages.getHead()); - List optionsResponseMessages = getResponseMessageList(globalResponseMessages.getOptions()); - List trackResponseMessages = getResponseMessageList(globalResponseMessages.getTrace()); + List postResponseMessages = getResponseMessageList(globalResponseMessages.getPost()); + List getResponseMessages = getResponseMessageList(globalResponseMessages.getGet()); + List putResponseMessages = getResponseMessageList(globalResponseMessages.getPut()); + List patchResponseMessages = getResponseMessageList(globalResponseMessages.getPatch()); + List deleteResponseMessages = getResponseMessageList(globalResponseMessages.getDelete()); + List headResponseMessages = getResponseMessageList(globalResponseMessages.getHead()); + List optionsResponseMessages = getResponseMessageList(globalResponseMessages.getOptions()); + List trackResponseMessages = getResponseMessageList(globalResponseMessages.getTrace()); docketForBuilder.useDefaultResponseMessages(swaggerProperties.getApplyDefaultResponseMessages()) - .globalResponseMessage(RequestMethod.POST, postResponseMessages) - .globalResponseMessage(RequestMethod.GET, getResponseMessages) - .globalResponseMessage(RequestMethod.PUT, putResponseMessages) - .globalResponseMessage(RequestMethod.PATCH, patchResponseMessages) - .globalResponseMessage(RequestMethod.DELETE, deleteResponseMessages) - .globalResponseMessage(RequestMethod.HEAD, headResponseMessages) - .globalResponseMessage(RequestMethod.OPTIONS, optionsResponseMessages) - .globalResponseMessage(RequestMethod.TRACE, trackResponseMessages); + .globalResponseMessage(RequestMethod.POST, postResponseMessages) + .globalResponseMessage(RequestMethod.GET, getResponseMessages) + .globalResponseMessage(RequestMethod.PUT, putResponseMessages) + .globalResponseMessage(RequestMethod.PATCH, patchResponseMessages) + .globalResponseMessage(RequestMethod.DELETE, deleteResponseMessages) + .globalResponseMessage(RequestMethod.HEAD, headResponseMessages) + .globalResponseMessage(RequestMethod.OPTIONS, optionsResponseMessages) + .globalResponseMessage(RequestMethod.TRACE, trackResponseMessages); } /** diff --git a/src/main/java/com/spring4all/swagger/SwaggerProperties.java b/src/main/java/com/spring4all/swagger/SwaggerProperties.java index 8c2616c..ed020dd 100644 --- a/src/main/java/com/spring4all/swagger/SwaggerProperties.java +++ b/src/main/java/com/spring4all/swagger/SwaggerProperties.java @@ -18,70 +18,118 @@ @ConfigurationProperties("swagger") public class SwaggerProperties { - /**是否开启swagger**/ + /** + * 是否开启swagger + **/ private Boolean enabled; - /**标题**/ + /** + * 标题 + **/ private String title = ""; - /**描述**/ + /** + * 描述 + **/ private String description = ""; - /**版本**/ + /** + * 版本 + **/ private String version = ""; - /**许可证**/ + /** + * 许可证 + **/ private String license = ""; - /**许可证URL**/ + /** + * 许可证URL + **/ private String licenseUrl = ""; - /**服务条款URL**/ + /** + * 服务条款URL + **/ private String termsOfServiceUrl = ""; - /**忽略的参数类型**/ + /** + * 忽略的参数类型 + **/ private List ignoredParameterTypes = new ArrayList<>(); private Contact contact = new Contact(); - /**swagger会解析的包路径**/ + /** + * swagger会解析的包路径 + **/ private String basePackage = ""; - /**swagger会解析的url规则**/ + /** + * swagger会解析的url规则 + **/ private List basePath = new ArrayList<>(); - /**在basePath基础上需要排除的url规则**/ + /** + * 在basePath基础上需要排除的url规则 + **/ private List excludePath = new ArrayList<>(); - /**分组文档**/ + /** + * 分组文档 + **/ private Map docket = new LinkedHashMap<>(); - /**host信息**/ + /** + * host信息 + **/ private String host = ""; - /**全局参数配置**/ + /** + * 全局参数配置 + **/ private List globalOperationParameters; - /** 页面功能配置 **/ + /** + * 页面功能配置 + **/ private UiConfig uiConfig = new UiConfig(); - /** 是否使用默认预定义的响应消息 ,默认 true **/ + /** + * 是否使用默认预定义的响应消息 ,默认 true + **/ private Boolean applyDefaultResponseMessages = true; - /** 全局响应消息 **/ + /** + * 全局响应消息 + **/ private GlobalResponseMessage globalResponseMessage; + /** + * 全局统一鉴权配置 + **/ + private Authorization authorization = new Authorization(); @Data @NoArgsConstructor - public static class GlobalOperationParameter{ - /**参数名**/ + public static class GlobalOperationParameter { + /** + * 参数名 + **/ private String name; - /**描述信息**/ + /** + * 描述信息 + **/ private String description; - /**指定参数类型**/ + /** + * 指定参数类型 + **/ private String modelRef; - /**参数放在哪个地方:header,query,path,body.form**/ + /** + * 参数放在哪个地方:header,query,path,body.form + **/ private String parameterType; - /**参数是否必须传**/ + /** + * 参数是否必须传 + **/ private String required; } @@ -90,32 +138,52 @@ public static class GlobalOperationParameter{ @NoArgsConstructor public static class DocketInfo { - /**标题**/ + /** + * 标题 + **/ private String title = ""; - /**描述**/ + /** + * 描述 + **/ private String description = ""; - /**版本**/ + /** + * 版本 + **/ private String version = ""; - /**许可证**/ + /** + * 许可证 + **/ private String license = ""; - /**许可证URL**/ + /** + * 许可证URL + **/ private String licenseUrl = ""; - /**服务条款URL**/ + /** + * 服务条款URL + **/ private String termsOfServiceUrl = ""; private Contact contact = new Contact(); - /**swagger会解析的包路径**/ + /** + * swagger会解析的包路径 + **/ private String basePackage = ""; - /**swagger会解析的url规则**/ + /** + * swagger会解析的url规则 + **/ private List basePath = new ArrayList<>(); - /**在basePath基础上需要排除的url规则**/ + /** + * 在basePath基础上需要排除的url规则 + **/ private List excludePath = new ArrayList<>(); private List globalOperationParameters; - /**忽略的参数类型**/ + /** + * 忽略的参数类型 + **/ private List ignoredParameterTypes = new ArrayList<>(); } @@ -124,11 +192,17 @@ public static class DocketInfo { @NoArgsConstructor public static class Contact { - /**联系人**/ + /** + * 联系人 + **/ private String name = ""; - /**联系人url**/ + /** + * 联系人url + **/ private String url = ""; - /**联系人email**/ + /** + * 联系人email + **/ private String email = ""; } @@ -137,28 +211,44 @@ public static class Contact { @NoArgsConstructor public static class GlobalResponseMessage { - /** POST 响应消息体 **/ + /** + * POST 响应消息体 + **/ List post = new ArrayList<>(); - /** GET 响应消息体 **/ + /** + * GET 响应消息体 + **/ List get = new ArrayList<>(); - /** PUT 响应消息体 **/ + /** + * PUT 响应消息体 + **/ List put = new ArrayList<>(); - /** PATCH 响应消息体 **/ + /** + * PATCH 响应消息体 + **/ List patch = new ArrayList<>(); - /** DELETE 响应消息体 **/ + /** + * DELETE 响应消息体 + **/ List delete = new ArrayList<>(); - /** HEAD 响应消息体 **/ + /** + * HEAD 响应消息体 + **/ List head = new ArrayList<>(); - /** OPTIONS 响应消息体 **/ + /** + * OPTIONS 响应消息体 + **/ List options = new ArrayList<>(); - /** TRACE 响应消息体 **/ + /** + * TRACE 响应消息体 + **/ List trace = new ArrayList<>(); } @@ -167,13 +257,19 @@ public static class GlobalResponseMessage { @NoArgsConstructor public static class GlobalResponseMessageBody { - /** 响应码 **/ + /** + * 响应码 + **/ private int code; - /** 响应消息 **/ + /** + * 响应消息 + **/ private String message; - /** 响应体 **/ + /** + * 响应体 + **/ private String modelRef; } @@ -188,17 +284,48 @@ public static class UiConfig { private String apiSorter = "alpha"; // alpha private String defaultModelRendering = "schema"; // schema - /** 是否启用json编辑器 **/ + /** + * 是否启用json编辑器 + **/ private Boolean jsonEditor = false; - /** 是否显示请求头信息 **/ + /** + * 是否显示请求头信息 + **/ private Boolean showRequestHeaders = true; - /** 支持页面提交的请求类型 **/ + /** + * 支持页面提交的请求类型 + **/ private String submitMethods = "get,post,put,delete,patch"; - /** 请求超时时间 **/ + /** + * 请求超时时间 + **/ private Long requestTimeout = 10000L; } + /** + * securitySchemes 支持方式之一 ApiKey + */ + @Data + @NoArgsConstructor + public static class Authorization { + + /** + * 鉴权 API-KEY 名称标识 + */ + private String name = "TOKEN"; + + /** + * 鉴权参数 + */ + private String keyName = "API-TOKEN"; + + /** + * 通过正则设置需要传递Authorization信息的API接口 + */ + private String authRegex = "^.*$"; + } + } From 7bc3473e68852ad8f7667268b9febb16bb04b26e Mon Sep 17 00:00:00 2001 From: LarryKoo Date: Wed, 21 Mar 2018 20:57:58 +0800 Subject: [PATCH 2/4] =?UTF-8?q?1.=20=E5=8D=87=E7=BA=A7spring-boot=E4=B8=BA?= =?UTF-8?q?1.5.10=E7=9A=84=E7=A8=B3=E5=AE=9A=E7=89=88=E6=9C=AC=EF=BC=9B=20?= =?UTF-8?q?2.=20=E4=BC=98=E5=8C=96springfox=E5=9C=A82.8=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=90=8E=E5=BA=9F=E5=BC=83=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=9B=203.=20=E6=A0=B8=E5=BF=83=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E4=B8=BB=E8=A6=81=E6=98=AF=E7=BB=88=E4=BA=8E=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86SecuritySchemes=E5=92=8CSecurityContexts=E5=9C=A8?= =?UTF-8?q?=E8=BF=99=E4=B8=AA=E7=89=88=E6=9C=AC=E7=9A=84=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E5=B7=B2=E7=BB=8F=E9=BB=98=E8=AE=A4=E5=BC=80?= =?UTF-8?q?=E5=90=AFApiKey=E6=A8=A1=E5=BC=8F=EF=BC=8C=E5=8F=AF=E8=87=AA?= =?UTF-8?q?=E7=94=B1=E9=85=8D=E7=BD=AE=EF=BC=9B=203.1=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?ApiKey("Authorization",=20"token",=20"^.*$")=EF=BC=8C=E5=88=86?= =?UTF-8?q?=E5=88=AB=E4=B8=BA=E9=89=B4=E6=9D=83=E7=AD=96=E7=95=A5ID?= =?UTF-8?q?=EF=BC=8C=E9=89=B4=E6=9D=83=E6=98=AFheader=E7=9A=84=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=90=8D=EF=BC=8C=E5=92=8C=E9=9C=80=E8=A6=81=E5=BC=80?= =?UTF-8?q?=E5=90=AF=E9=89=B4=E6=9D=83URL=E7=9A=84=E6=AD=A3=E5=88=99?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../swagger/SwaggerAutoConfiguration.java | 95 +++++++++++-------- .../spring4all/swagger/SwaggerProperties.java | 47 +++++++-- 3 files changed, 93 insertions(+), 51 deletions(-) diff --git a/pom.xml b/pom.xml index f3c96a8..8fc9532 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ UTF-8 1.8 2.8.0 - 1.5.9.RELEASE + 1.5.10.RELEASE 1.16.18 diff --git a/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java b/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java index 2929252..143dd4e 100644 --- a/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java +++ b/src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java @@ -20,7 +20,9 @@ import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger.web.ApiKeyVehicle; import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; import java.util.*; import java.util.stream.Collectors; @@ -48,15 +50,20 @@ public SwaggerProperties swaggerProperties() { @Bean public UiConfiguration uiConfiguration(SwaggerProperties swaggerProperties) { - return new UiConfiguration( - swaggerProperties.getUiConfig().getValidatorUrl(),// url - swaggerProperties.getUiConfig().getDocExpansion(), // docExpansion => none | list - swaggerProperties.getUiConfig().getApiSorter(), // apiSorter => alpha - swaggerProperties.getUiConfig().getDefaultModelRendering(), // defaultModelRendering => schema - swaggerProperties.getUiConfig().getSubmitMethods().split(","), - swaggerProperties.getUiConfig().getJsonEditor(), // enableJsonEditor => true | false - swaggerProperties.getUiConfig().getShowRequestHeaders(), // showRequestHeaders => true | false - swaggerProperties.getUiConfig().getRequestTimeout()); // requestTimeout => in milliseconds, defaults to null (uses jquery xh timeout) + return UiConfigurationBuilder.builder() + .deepLinking(swaggerProperties.getUiConfig().getDeepLinking()) + .defaultModelExpandDepth(swaggerProperties.getUiConfig().getDefaultModelExpandDepth()) + .defaultModelRendering(swaggerProperties.getUiConfig().getDefaultModelRendering()) + .defaultModelsExpandDepth(swaggerProperties.getUiConfig().getDefaultModelsExpandDepth()) + .displayOperationId(swaggerProperties.getUiConfig().getDisplayOperationId()) + .displayRequestDuration(swaggerProperties.getUiConfig().getDisplayRequestDuration()) + .docExpansion(swaggerProperties.getUiConfig().getDocExpansion()) + .maxDisplayedTags(swaggerProperties.getUiConfig().getMaxDisplayedTags()) + .operationsSorter(swaggerProperties.getUiConfig().getOperationsSorter()) + .showExtensions(swaggerProperties.getUiConfig().getShowExtensions()) + .tagsSorter(swaggerProperties.getUiConfig().getTagsSorter()) + .validatorUrl(swaggerProperties.getUiConfig().getValidatorUrl()) + .build(); } @Bean @@ -92,7 +99,7 @@ public List createRestApi(SwaggerProperties swaggerProperties) { } // exclude-path处理 - List> excludePath = new ArrayList(); + List> excludePath = new ArrayList<>(); for (String path : swaggerProperties.getExcludePath()) { excludePath.add(PathSelectors.ant(path)); } @@ -100,8 +107,8 @@ public List createRestApi(SwaggerProperties swaggerProperties) { Docket docketForBuilder = new Docket(DocumentationType.SWAGGER_2) .host(swaggerProperties.getHost()) .apiInfo(apiInfo) - .securitySchemes(this.securitySchemes()) - .securityContexts(this.securityContexts()) + .securitySchemes(Collections.singletonList(apiKey())) + .securityContexts(Collections.singletonList(securityContext())) .globalOperationParameters(buildGlobalOperationParametersFromSwaggerProperties( swaggerProperties.getGlobalOperationParameters())); @@ -119,9 +126,9 @@ public List createRestApi(SwaggerProperties swaggerProperties) { ) ).build(); - /** ignoredParameterTypes **/ - Class[] array = new Class[swaggerProperties.getIgnoredParameterTypes().size()]; - Class[] ignoredParameterTypes = swaggerProperties.getIgnoredParameterTypes().toArray(array); + /* ignoredParameterTypes **/ + Class[] array = new Class[swaggerProperties.getIgnoredParameterTypes().size()]; + Class[] ignoredParameterTypes = swaggerProperties.getIgnoredParameterTypes().toArray(array); docket.ignoredParameterTypes(ignoredParameterTypes); configurableBeanFactory.registerSingleton("defaultDocket", docket); @@ -168,8 +175,8 @@ public List createRestApi(SwaggerProperties swaggerProperties) { Docket docketForBuilder = new Docket(DocumentationType.SWAGGER_2) .host(swaggerProperties.getHost()) .apiInfo(apiInfo) - .securitySchemes(this.securitySchemes()) - .securityContexts(this.securityContexts()) + .securitySchemes(Collections.singletonList(apiKey())) + .securityContexts(Collections.singletonList(securityContext())) .globalOperationParameters(assemblyGlobalOperationParameters(swaggerProperties.getGlobalOperationParameters(), docketInfo.getGlobalOperationParameters())); @@ -189,9 +196,9 @@ public List createRestApi(SwaggerProperties swaggerProperties) { ) .build(); - /** ignoredParameterTypes **/ - Class[] array = new Class[docketInfo.getIgnoredParameterTypes().size()]; - Class[] ignoredParameterTypes = docketInfo.getIgnoredParameterTypes().toArray(array); + /* ignoredParameterTypes **/ + Class[] array = new Class[docketInfo.getIgnoredParameterTypes().size()]; + Class[] ignoredParameterTypes = docketInfo.getIgnoredParameterTypes().toArray(array); docket.ignoredParameterTypes(ignoredParameterTypes); configurableBeanFactory.registerSingleton(groupName, docket); @@ -201,36 +208,41 @@ public List createRestApi(SwaggerProperties swaggerProperties) { } /** - * 配置 Authorization ApiKey + * 配置基于 ApiKey 的鉴权对象 * * @return */ - private List securitySchemes() { - return newArrayList( - new ApiKey(swaggerProperties().getAuthorization().getName(), - swaggerProperties().getAuthorization().getKeyName(), "header")); + private ApiKey apiKey() { + return new ApiKey(swaggerProperties().getAuthorization().getName(), + swaggerProperties().getAuthorization().getKeyName(), + ApiKeyVehicle.HEADER.getValue()); } /** - * 通过正则设置需要传递 Authorization 信息的API接口 + * 配置默认的全局鉴权策略的开关,以及通过正则表达式进行匹配;默认 ^.*$ 匹配所有URL + * 其中 securityReferences 为配置启用的鉴权策略 * * @return */ - private List securityContexts() { - return newArrayList( - SecurityContext.builder() - .securityReferences(defaultAuth()) - .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex())) - .build() - ); + private SecurityContext securityContext() { + return SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex())) + .build(); } - List defaultAuth() { + /** + * 配置默认的全局鉴权策略;其中返回的 SecurityReference 中,reference 即为ApiKey对象里面的name,保持一致才能开启全局鉴权 + * + * @return + */ + private List defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; - return newArrayList( - new SecurityReference("BearerToken", authorizationScopes)); + return Collections.singletonList(SecurityReference.builder() + .reference(swaggerProperties().getAuthorization().getName()) + .scopes(authorizationScopes).build()); } @@ -295,15 +307,15 @@ private List assemblyGlobalOperationParameters( /** * 设置全局响应消息 * - * @param swaggerProperties 支持 POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE - * @param docketForBuilder + * @param swaggerProperties swaggerProperties 支持 POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE + * @param docketForBuilder swagger docket builder */ private void buildGlobalResponseMessage(SwaggerProperties swaggerProperties, Docket docketForBuilder) { SwaggerProperties.GlobalResponseMessage globalResponseMessages = swaggerProperties.getGlobalResponseMessage(); - // POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE 响应消息体 + /* POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE 响应消息体 **/ List postResponseMessages = getResponseMessageList(globalResponseMessages.getPost()); List getResponseMessages = getResponseMessageList(globalResponseMessages.getGet()); List putResponseMessages = getResponseMessageList(globalResponseMessages.getPut()); @@ -327,10 +339,11 @@ private void buildGlobalResponseMessage(SwaggerProperties swaggerProperties, Doc /** * 获取返回消息体列表 * - * @param globalResponseMessageBodyList + * @param globalResponseMessageBodyList 全局Code消息返回集合 * @return */ - private List getResponseMessageList(List globalResponseMessageBodyList) { + private List getResponseMessageList + (List globalResponseMessageBodyList) { List responseMessages = new ArrayList<>(); for (SwaggerProperties.GlobalResponseMessageBody globalResponseMessageBody : globalResponseMessageBodyList) { ResponseMessageBuilder responseMessageBuilder = new ResponseMessageBuilder(); diff --git a/src/main/java/com/spring4all/swagger/SwaggerProperties.java b/src/main/java/com/spring4all/swagger/SwaggerProperties.java index ed020dd..9193036 100644 --- a/src/main/java/com/spring4all/swagger/SwaggerProperties.java +++ b/src/main/java/com/spring4all/swagger/SwaggerProperties.java @@ -3,6 +3,10 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.boot.context.properties.ConfigurationProperties; +import springfox.documentation.swagger.web.DocExpansion; +import springfox.documentation.swagger.web.ModelRendering; +import springfox.documentation.swagger.web.OperationsSorter; +import springfox.documentation.swagger.web.TagsSorter; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -51,7 +55,7 @@ public class SwaggerProperties { /** * 忽略的参数类型 **/ - private List ignoredParameterTypes = new ArrayList<>(); + private List> ignoredParameterTypes = new ArrayList<>(); private Contact contact = new Contact(); @@ -184,7 +188,7 @@ public static class DocketInfo { /** * 忽略的参数类型 **/ - private List ignoredParameterTypes = new ArrayList<>(); + private List> ignoredParameterTypes = new ArrayList<>(); } @@ -279,10 +283,8 @@ public static class GlobalResponseMessageBody { @NoArgsConstructor public static class UiConfig { - private String validatorUrl; - private String docExpansion = "none"; // none | list - private String apiSorter = "alpha"; // alpha - private String defaultModelRendering = "schema"; // schema + + private String apiSorter = "alpha"; /** * 是否启用json编辑器 @@ -301,6 +303,33 @@ public static class UiConfig { **/ private Long requestTimeout = 10000L; + private Boolean deepLinking; + private Boolean displayOperationId; + private Integer defaultModelsExpandDepth; + private Integer defaultModelExpandDepth; + private ModelRendering defaultModelRendering; + + /** + * 是否显示请求耗时,默认false + */ + private Boolean displayRequestDuration = true; + /** + * 可选 none | list + */ + private DocExpansion docExpansion; + /** + * Boolean=false OR String + */ + private Object filter; + private Integer maxDisplayedTags; + private OperationsSorter operationsSorter; + private Boolean showExtensions; + private TagsSorter tagsSorter; + + /** + * Network + */ + private String validatorUrl; } /** @@ -308,17 +337,17 @@ public static class UiConfig { */ @Data @NoArgsConstructor - public static class Authorization { + static class Authorization { /** * 鉴权 API-KEY 名称标识 */ - private String name = "TOKEN"; + private String name = "Authorization"; /** * 鉴权参数 */ - private String keyName = "API-TOKEN"; + private String keyName = "TOKEN"; /** * 通过正则设置需要传递Authorization信息的API接口 From cc7bff7788c601789e06adf34cd5b7a934f9b440 Mon Sep 17 00:00:00 2001 From: LarryKoo Date: Wed, 21 Mar 2018 21:29:39 +0800 Subject: [PATCH 3/4] =?UTF-8?q?1.7.0=20=E6=9B=B4=E6=96=B0=EF=BC=8C?= =?UTF-8?q?=E6=9D=A5=E8=87=AA2018=E5=B9=B4=E7=9A=84=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=EF=BC=8C=E6=AC=A2=E5=91=BC=E5=90=A7=EF=BC=8C?= =?UTF-8?q?Coder=E4=BB=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 98 ++++++++++++++++++- pom.xml | 2 +- .../spring4all/swagger/SwaggerProperties.java | 6 +- 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1f7a6b9..964a1a5 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ # 版本基础 - Spring Boot:1.5.x -- Swagger:2.7.x +- Swagger:2.8.x # 如何使用 @@ -24,15 +24,17 @@ - 在`pom.xml`中引入依赖: +> 当前最新版本 1.7.0.RELEASE + ```xml com.spring4all swagger-spring-boot-starter - 1.6.0.RELEASE + 1.7.0.RELEASE ``` -**注意:从`1.6.0`开始,我们按Spring Boot官方建议修改了artifactId为`swagger-spring-boot-starter`,1.6.0之前的版本不做修改,依然为使用`spring-boot-starter-swagger` !** +**注意:从`1.6.1`开始,我们按Spring Boot官方建议修改了artifactId为`swagger-spring-boot-starter`,1.6.0之前的版本不做修改,依然为使用`spring-boot-starter-swagger` !** - 在应用主类中增加`@EnableSwagger2Doc`注解 @@ -249,13 +251,102 @@ swagger.ui-config.submit-methods=get,delete swagger.ui-config.submit-methods= ``` +--- + +### 来自2018年的版本升级,欢呼吧,Coder们 + +> 2018-03-21 今日春分,细雨如风 `1.7.0` 版本诞生 @gumutianqi + +#### UI升级到 2.8.0 版本 (1.7.0 + 支持) + +- 扁平化设计 +- 更加华丽 +- 更加易用 +- 可配置项更加自由 + + +### Authorization 鉴权配置 (1.7.0 + 支持) + +- 新增 Authorization 配置项 + +```properties +# 鉴权策略ID,对应 SecurityReferences ID +swagger.authorization.name=Authorization + +# 鉴权传递的Header参数 +swagger.authorization.key-name=token + +# 需要开启鉴权URL的正则, 默认^.*$匹配所有URL +swagger.authorization.auth-regex=^.*$ +``` + +备注:目前支持`ApiKey`鉴权模式,后续添加`Oauth2`和`BasicAuth`支持 + +##### 使用须知 + +> 1. 默认已经在全局开启了`global`的SecurityReferences,无需配置任何参数就可以使用; +> 2. 全局鉴权的范围在可以通过以上参数`auth-regex`进行正则表达式匹配控制; +> 3. 除了全局开启外,还可以手动通过注解在RestController上进行定义鉴权,使用方式如下: + +```java +// 其中的ID Authorization 即为配置项 swagger.authorization.name,详细请关注后面的配置代码 +@ApiOperation(value = "Hello World", authorizations = {@Authorization(value = "Authorization")}) +@RequestMapping(value = "/hello", method = RequestMethod.GET) +String hello(); +``` + +##### 关于如何配置实现鉴权,请关注以下code: + +```java +/** + * 配置基于 ApiKey 的鉴权对象 + * + * @return + */ +private ApiKey apiKey() { + return new ApiKey(swaggerProperties().getAuthorization().getName(), + swaggerProperties().getAuthorization().getKeyName(), + ApiKeyVehicle.HEADER.getValue()); +} + +/** + * 配置默认的全局鉴权策略的开关,以及通过正则表达式进行匹配;默认 ^.*$ 匹配所有URL + * 其中 securityReferences 为配置启用的鉴权策略 + * + * @return + */ +private SecurityContext securityContext() { + return SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex())) + .build(); +} + +/** + * 配置默认的全局鉴权策略;其中返回的 SecurityReference 中,reference 即为ApiKey对象里面的name,保持一致才能开启全局鉴权 + * + * @return + */ +private List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + return Collections.singletonList(SecurityReference.builder() + .reference(swaggerProperties().getAuthorization().getName()) + .scopes(authorizationScopes).build()); +} +``` + + - 其他配置 ```properties # json编辑器 swagger.ui-config.json-editor=false + # 显示请求头 swagger.ui-config.show-request-headers=true + # 页面调试请求的超时时间 swagger.ui-config.request-timeout=5000 ``` @@ -281,3 +372,4 @@ swagger.docket.aaa.ignored-parameter-types[1]=com.didispace.demo.Product - [程序猿DD-翟永超](https://github.com/dyc87112/) - [小火](https://renlulu.github.io/) - [泥瓦匠BYSocket](https://github.com/JeffLi1993) +- [LarryKoo-古拉里](https://github.com/gumutianqi) diff --git a/pom.xml b/pom.xml index 8fc9532..2a249ca 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.spring4all swagger-spring-boot-starter - 1.6.1.RELEASE + 1.7.0.RELEASE spring-boot-starter-swagger https://github.com/SpringForAll/spring-boot-starter-swagger diff --git a/src/main/java/com/spring4all/swagger/SwaggerProperties.java b/src/main/java/com/spring4all/swagger/SwaggerProperties.java index 9193036..0a43142 100644 --- a/src/main/java/com/spring4all/swagger/SwaggerProperties.java +++ b/src/main/java/com/spring4all/swagger/SwaggerProperties.java @@ -340,17 +340,17 @@ public static class UiConfig { static class Authorization { /** - * 鉴权 API-KEY 名称标识 + * 鉴权策略ID,对应 SecurityReferences ID */ private String name = "Authorization"; /** - * 鉴权参数 + * 鉴权传递的Header参数 */ private String keyName = "TOKEN"; /** - * 通过正则设置需要传递Authorization信息的API接口 + * 需要开启鉴权URL的正则 */ private String authRegex = "^.*$"; } From 6542bb9c50de308c08359a1bddaa7831129fa59b Mon Sep 17 00:00:00 2001 From: zhaiyongchao Date: Thu, 22 Mar 2018 09:19:37 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 69 +++++++++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 964a1a5..379d966 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # 简介 -[![Build Status](https://travis-ci.org/dyc87112/spring-boot-starter-swagger.svg?branch=1.5.0)](https://travis-ci.org/dyc87112/spring-boot-starter-swagger) - 该项目主要利用Spring Boot的自动化配置特性来实现快速的将swagger2引入spring boot应用来生成API文档,简化原生使用swagger2的整合代码。 - 源码地址 @@ -34,7 +32,7 @@ ``` -**注意:从`1.6.1`开始,我们按Spring Boot官方建议修改了artifactId为`swagger-spring-boot-starter`,1.6.0之前的版本不做修改,依然为使用`spring-boot-starter-swagger` !** +**注意:从`1.6.0`开始,我们按Spring Boot官方建议修改了artifactId为`swagger-spring-boot-starter`,1.6.0之前的版本不做修改,依然为使用`spring-boot-starter-swagger` !** - 在应用主类中增加`@EnableSwagger2Doc`注解 @@ -251,19 +249,34 @@ swagger.ui-config.submit-methods=get,delete swagger.ui-config.submit-methods= ``` ---- +- 其他配置 -### 来自2018年的版本升级,欢呼吧,Coder们 +```properties +# json编辑器 +swagger.ui-config.json-editor=false -> 2018-03-21 今日春分,细雨如风 `1.7.0` 版本诞生 @gumutianqi +# 显示请求头 +swagger.ui-config.show-request-headers=true -#### UI升级到 2.8.0 版本 (1.7.0 + 支持) +# 页面调试请求的超时时间 +swagger.ui-config.request-timeout=5000 +``` -- 扁平化设计 -- 更加华丽 -- 更加易用 -- 可配置项更加自由 +### ignoredParameterTypes配置(1.6.0 + 支持) +```properties +# 基础配置 +swagger.ignored-parameter-types[0]=com.didispace.demo.User +swagger.ignored-parameter-types[1]=com.didispace.demo.Product + +# 分组配置 +swagger.docket.aaa.ignored-parameter-types[0]=com.didispace.demo.User +swagger.docket.aaa.ignored-parameter-types[1]=com.didispace.demo.Product +``` + +> 该参数作用: +> Q. Infinite loop when springfox tries to determine schema for objects with nested/complex constraints? +> A. If you have recursively defined objects, I would try and see if providing an alternate type might work or perhaps even ignoring the offending classes e.g. order using the docket. ignoredParameterTypes(Order.class). This is usually found in Hibernate domain objects that have bidirectional dependencies on other objects. ### Authorization 鉴权配置 (1.7.0 + 支持) @@ -282,7 +295,7 @@ swagger.authorization.auth-regex=^.*$ 备注:目前支持`ApiKey`鉴权模式,后续添加`Oauth2`和`BasicAuth`支持 -##### 使用须知 +**使用须知** > 1. 默认已经在全局开启了`global`的SecurityReferences,无需配置任何参数就可以使用; > 2. 全局鉴权的范围在可以通过以上参数`auth-regex`进行正则表达式匹配控制; @@ -295,7 +308,7 @@ swagger.authorization.auth-regex=^.*$ String hello(); ``` -##### 关于如何配置实现鉴权,请关注以下code: +**关于如何配置实现鉴权,请关注以下code:** ```java /** @@ -337,36 +350,6 @@ private List defaultAuth() { } ``` - -- 其他配置 - -```properties -# json编辑器 -swagger.ui-config.json-editor=false - -# 显示请求头 -swagger.ui-config.show-request-headers=true - -# 页面调试请求的超时时间 -swagger.ui-config.request-timeout=5000 -``` - -### ignoredParameterTypes配置(1.6.0 + 支持) - -```properties -# 基础配置 -swagger.ignored-parameter-types[0]=com.didispace.demo.User -swagger.ignored-parameter-types[1]=com.didispace.demo.Product - -# 分组配置 -swagger.docket.aaa.ignored-parameter-types[0]=com.didispace.demo.User -swagger.docket.aaa.ignored-parameter-types[1]=com.didispace.demo.Product -``` - -> 该参数作用: -> Q. Infinite loop when springfox tries to determine schema for objects with nested/complex constraints? -> A. If you have recursively defined objects, I would try and see if providing an alternate type might work or perhaps even ignoring the offending classes e.g. order using the docket. ignoredParameterTypes(Order.class). This is usually found in Hibernate domain objects that have bidirectional dependencies on other objects. - ## 贡献者 - [程序猿DD-翟永超](https://github.com/dyc87112/)