From edfb7a73885d39f501200bb6da3f25eef8a5fcaa Mon Sep 17 00:00:00 2001
From: Haotian Zhang <928016560@qq.com>
Date: Tue, 26 Sep 2023 18:55:34 +0800
Subject: [PATCH] feat:add swagger exposure filters. (#1146)
---
CHANGELOG.md | 3 +-
README-zh.md | 2 +-
README.md | 2 +-
pom.xml | 2 +-
.../contract/PolarisContractReporter.java | 11 +--
.../contract/config/ContractProperties.java | 4 +
.../config/PolarisContractProperties.java | 15 ++++
.../PolarisSwaggerAutoConfiguration.java | 68 +++++++++++++++--
.../contract/filter/ApiDocServletFilter.java | 73 +++++++++++++++++++
.../contract/filter/ApiDocWebFluxFilter.java | 71 ++++++++++++++++++
.../contract/filter/FilterConstant.java | 64 ++++++++++++++++
.../polaris/contract/utils/PackageUtil.java | 1 -
...itional-spring-configuration-metadata.json | 40 ++++++++++
.../discovery-callee-service/pom.xml | 8 +-
.../src/main/resources/bootstrap.yml | 2 +
.../src/main/resources/bootstrap.yml | 2 +
16 files changed, 346 insertions(+), 22 deletions(-)
create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java
create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java
create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java
create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d61a882fa..6c9822955 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,4 +8,5 @@
- [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128)
- [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129)
- [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136)
-- [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139)
\ No newline at end of file
+- [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139)
+- [feat:add swagger exposure filters.](https://github.com/Tencent/spring-cloud-tencent/pull/1146)
diff --git a/README-zh.md b/README-zh.md
index 548c7ff73..b4447195a 100644
--- a/README-zh.md
+++ b/README-zh.md
@@ -78,7 +78,7 @@ Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要
com.tencent.cloud
spring-cloud-tencent-dependencies
- 1.12.0-2021.0.8
+ 1.12.1-2021.0.8
pom
import
diff --git a/README.md b/README.md
index 17092db54..2cb1f52e7 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ For example:
com.tencent.cloud
spring-cloud-tencent-dependencies
- 1.12.0-2021.0.8
+ 1.12.1-2021.0.8
pom
import
diff --git a/pom.xml b/pom.xml
index 09ad0369b..2b46501a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,7 +92,7 @@
1.13.0-2021.0.8-SNAPSHOT
- 5.3.29
+ 5.3.25
2.6.15
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java
index dd421b45b..2321c0c90 100644
--- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java
@@ -36,7 +36,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;
-import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;
import org.springframework.boot.context.event.ApplicationReadyEvent;
@@ -44,12 +43,16 @@ import org.springframework.context.ApplicationListener;
import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
+/**
+ * Polaris contract reporter.
+ *
+ * @author Haotian Zhang
+ */
public class PolarisContractReporter implements ApplicationListener {
private final Logger LOG = LoggerFactory.getLogger(PolarisContractReporter.class);
private final ServiceModelToSwagger2Mapper swagger2Mapper;
private final DocumentationCache documentationCache;
- private final JsonSerializer jsonSerializer;
private final String groupName;
private final ProviderAPI providerAPI;
@@ -57,11 +60,9 @@ public class PolarisContractReporter implements ApplicationListener void customizeSpringfoxHandlerMappings(List mappings) {
+ List copy = mappings.stream()
+ .filter(mapping -> mapping.getPatternParser() == null)
+ .collect(Collectors.toList());
+ mappings.clear();
+ mappings.addAll(copy);
+ }
+
+ @SuppressWarnings("unchecked")
+ private List getHandlerMappings(Object bean) {
+ try {
+ Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
+ field.setAccessible(true);
+ return (List) field.get(bean);
+ }
+ catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ };
+ }
+ @Bean
+ public ApiDocServletFilter apiDocServletFilter(PolarisContractProperties polarisContractProperties) {
+ return new ApiDocServletFilter(polarisContractProperties);
+ }
}
/**
@@ -142,6 +191,9 @@ public class PolarisSwaggerAutoConfiguration {
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
protected static class SwaggerReactiveConfig {
-
+ @Bean
+ public ApiDocWebFluxFilter apiDocWebFluxFilter(PolarisContractProperties polarisContractProperties) {
+ return new ApiDocWebFluxFilter(polarisContractProperties);
+ }
}
}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java
new file mode 100644
index 000000000..38aa3d7c9
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java
@@ -0,0 +1,73 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.filter;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.tencent.cloud.polaris.contract.config.PolarisContractProperties;
+
+import org.springframework.lang.NonNull;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_RESOURCE_PREFIX;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V2_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V3_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V2_API_DOC_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V3_API_DOC_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V2_PREFIX;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V3_PREFIX;
+
+/**
+ * Filter to disable api doc controller.
+ *
+ * @author Haotian Zhang
+ */
+public class ApiDocServletFilter extends OncePerRequestFilter {
+
+ private final PolarisContractProperties polarisContractProperties;
+
+ public ApiDocServletFilter(PolarisContractProperties polarisContractProperties) {
+ this.polarisContractProperties = polarisContractProperties;
+ }
+
+ @Override
+ public void doFilterInternal(@NonNull HttpServletRequest httpServletRequest,
+ @NonNull HttpServletResponse httpServletResponse, @NonNull FilterChain filterChain)
+ throws ServletException, IOException {
+ if (!polarisContractProperties.isExposure()) {
+ String path = httpServletRequest.getServletPath();
+ if (path.startsWith(SWAGGER_V2_API_DOC_URL) ||
+ path.startsWith(SWAGGER_V3_API_DOC_URL) ||
+ path.startsWith(SWAGGER_UI_V2_URL) ||
+ path.startsWith(SWAGGER_UI_V3_URL) ||
+ path.startsWith(SWAGGER_RESOURCE_PREFIX) ||
+ path.startsWith(SWAGGER_WEBJARS_V2_PREFIX) ||
+ path.startsWith(SWAGGER_WEBJARS_V3_PREFIX)) {
+ httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ }
+ filterChain.doFilter(httpServletRequest, httpServletResponse);
+ }
+}
+
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java
new file mode 100644
index 000000000..7e7ea199a
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java
@@ -0,0 +1,71 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.filter;
+
+
+import com.tencent.cloud.polaris.contract.config.PolarisContractProperties;
+import reactor.core.publisher.Mono;
+
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_RESOURCE_PREFIX;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V2_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V3_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V2_API_DOC_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V3_API_DOC_URL;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V2_PREFIX;
+import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V3_PREFIX;
+
+/**
+ * Filter to disable api doc controller.
+ *
+ * @author Haotian Zhang
+ */
+public class ApiDocWebFluxFilter implements WebFilter {
+ private final PolarisContractProperties polarisContractProperties;
+
+ public ApiDocWebFluxFilter(PolarisContractProperties polarisContractProperties) {
+ this.polarisContractProperties = polarisContractProperties;
+ }
+
+ @Override
+ public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
+ if (!polarisContractProperties.isExposure()) {
+ String path = serverWebExchange.getRequest().getURI().getPath();
+ if (path.startsWith(SWAGGER_V2_API_DOC_URL) ||
+ path.startsWith(SWAGGER_V3_API_DOC_URL) ||
+ path.startsWith(SWAGGER_UI_V2_URL) ||
+ path.startsWith(SWAGGER_UI_V3_URL) ||
+ path.startsWith(SWAGGER_RESOURCE_PREFIX) ||
+ path.startsWith(SWAGGER_WEBJARS_V2_PREFIX) ||
+ path.startsWith(SWAGGER_WEBJARS_V3_PREFIX)) {
+ ServerHttpResponse response = serverWebExchange.getResponse();
+ response.setRawStatusCode(HttpStatus.FORBIDDEN.value());
+ DataBuffer dataBuffer = response.bufferFactory().allocateBuffer();
+ return response.writeWith(Mono.just(dataBuffer));
+ }
+ }
+ return webFilterChain.filter(serverWebExchange);
+ }
+}
+
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java
new file mode 100644
index 000000000..d95ae14fa
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java
@@ -0,0 +1,64 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.filter;
+
+/**
+ * Constant for filter.
+ *
+ * @author Haotian Zhang
+ */
+public final class FilterConstant {
+
+ /**
+ * Swagger api doc V2 url.
+ */
+ public static final String SWAGGER_V2_API_DOC_URL = "/v2/api-docs";
+
+ /**
+ * Swagger api doc V3 url.
+ */
+ public static final String SWAGGER_V3_API_DOC_URL = "/v3/api-docs";
+
+ /**
+ * Swagger UI V2 url.
+ */
+ public static final String SWAGGER_UI_V2_URL = "/swagger-ui.html";
+
+ /**
+ * Swagger UI V3 url.
+ */
+ public static final String SWAGGER_UI_V3_URL = "/swagger-ui/index.html";
+
+ /**
+ * Swagger resource url prefix.
+ */
+ public static final String SWAGGER_RESOURCE_PREFIX = "/swagger-resource/";
+
+ /**
+ * Swagger webjars V2 url prefix.
+ */
+ public static final String SWAGGER_WEBJARS_V2_PREFIX = "/webjars/springfox-swagger-ui/";
+
+ /**
+ * Swagger webjars V3 url prefix.
+ */
+ public static final String SWAGGER_WEBJARS_V3_PREFIX = "/webjars/swagger-ui/";
+
+ private FilterConstant() {
+ }
+}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java
index 7ce8a7ec2..1ce380cf5 100644
--- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java
@@ -48,7 +48,6 @@ public final class PackageUtil {
private static final String SPLITTER = ",";
-
private PackageUtil() {
}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json
new file mode 100644
index 000000000..4e5e4b72d
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -0,0 +1,40 @@
+{
+ "properties": [
+ {
+ "name": "spring.cloud.polaris.contract.enabled",
+ "type": "java.lang.Boolean",
+ "defaultValue": true,
+ "description": "Enable polaris record contract or not."
+ },
+ {
+ "name": "spring.cloud.polaris.contract.basePackage",
+ "type": "java.lang.String",
+ "defaultValue": "",
+ "description": "Packages to be scanned. Split by \",\"."
+ },
+ {
+ "name": "spring.cloud.polaris.contract.excludePath",
+ "type": "java.lang.String",
+ "defaultValue": "",
+ "description": "Paths to be excluded. Split by \",\"."
+ },
+ {
+ "name": "spring.cloud.polaris.contract.group",
+ "type": "java.lang.String",
+ "defaultValue": "default",
+ "description": "Group to create swagger docket."
+ },
+ {
+ "name": "spring.cloud.polaris.contract.basePath",
+ "type": "java.lang.String",
+ "defaultValue": "/**",
+ "description": "Base paths to be scanned. Split by \",\"."
+ },
+ {
+ "name": "spring.cloud.polaris.contract.exposure",
+ "type": "java.lang.Boolean",
+ "defaultValue": "true",
+ "description": "Enable polaris contract exposure or not."
+ }
+ ]
+}
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml
index 9b974df4c..312b45c1a 100644
--- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml
@@ -19,10 +19,10 @@
spring-boot-starter-webflux
-
-
-
-
+
+ com.tencent.cloud
+ spring-cloud-starter-tencent-polaris-contract
+
com.tencent.cloud
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml
index ec34c0c35..1f3a5b9e5 100644
--- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml
+++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml
@@ -11,6 +11,8 @@ spring:
discovery:
enabled: true
register: true
+ contract:
+ exposure: true
stat:
enabled: true
port: 28082
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml
index 71f388051..bcd78ef70 100644
--- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml
+++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml
@@ -22,6 +22,8 @@ spring:
heartbeat:
enabled: true
health-check-url: /discovery/service/caller/healthCheck
+ contract:
+ exposure: true
stat:
enabled: true
port: 28081