commit:集成knife4j

This commit is contained in:
Jerry
2020-10-29 18:51:32 +08:00
parent c87e94d2e8
commit 6e57f10dfc
648 changed files with 6447 additions and 708 deletions

View File

@@ -15,6 +15,31 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-ui:2.0.5" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.21" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-gateway:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:2.2.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
@@ -39,7 +64,6 @@
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webflux:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.synchronoss.cloud:nio-multipart-parser:1.1.0" level="project" />
<orderEntry type="library" name="Maven: org.synchronoss.cloud:nio-stream-storage:1.1.3" level="project" />
@@ -72,13 +96,6 @@
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
@@ -86,9 +103,9 @@
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.1.5" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.70" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
@@ -165,7 +182,6 @@
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-client-default:1.7.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-datasource:2.2.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.woodstox:stax2-api:4.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.woodstox:woodstox-core:5.0.3" level="project" />
@@ -178,9 +194,6 @@
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />
@@ -241,7 +254,6 @@
<orderEntry type="library" name="Maven: com.github.luben:zstd-jni:1.4.3-1" level="project" />
<orderEntry type="library" name="Maven: org.lz4:lz4-java:1.6.0" level="project" />
<orderEntry type="library" name="Maven: org.xerial.snappy:snappy-java:1.1.7.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.scala-lang:scala-library:2.12.10" level="project" />
<orderEntry type="library" name="Maven: com.lmax:disruptor:3.4.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.2.5.RELEASE" level="project" />

View File

@@ -14,6 +14,33 @@
<packaging>jar</packaging>
<dependencies>
<!-- swagger和knife4j相关集成-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${springfox.version}</version>
</dependency>
<!-- 网关服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>

View File

@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
* 网关服务启动类。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@SpringCloudApplication

View File

@@ -5,11 +5,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.Set;
/**
* 网关业务配置类。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Data
@RefreshScope
@@ -18,7 +20,7 @@ import org.springframework.context.annotation.Configuration;
public class ApplicationConfig {
/**
* token加密时的盐
* token加密用的密钥该值的长度最少10个字符(过短会报错)。
*/
private String tokenSigningKey;
/**
@@ -47,4 +49,12 @@ public class ApplicationConfig {
* 缺省值是 one day
*/
private int permRedisExpiredSeconds = 86400;
/**
* 基于完全等于(equals)判定规则的白名单地址集合过滤效率高于whitelistUrlPattern。
*/
private Set<String> whitelistUrl;
/**
* 基于Ant Pattern模式判定规则的白名单地址集合。如/aa/**。
*/
private Set<String> whitelistUrlPattern;
}

View File

@@ -12,7 +12,7 @@ import org.springframework.web.util.pattern.PathPatternParser;
* 跨域信任配置类。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Configuration
public class CorsConfig {

View File

@@ -11,7 +11,7 @@ import java.nio.charset.StandardCharsets;
* Web通用过滤器配置类。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Configuration
public class FilterConfig {

View File

@@ -17,7 +17,7 @@ import java.util.*;
* Spring Cloud Gateway的Sentinel流控配置类。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Configuration
public class SentinelConfig {

View File

@@ -0,0 +1,52 @@
package com.orange.demo.gateway.config;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import java.util.ArrayList;
import java.util.List;
/***
* 返回Swagger UI需要读取的资源数据这里是微服务的路由数据。
*
* @author Knife4j Team。
* @date 2020-08-08
*/
@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(route -> route.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("**", "v2/api-docs")))));
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}

View File

@@ -4,7 +4,7 @@ package com.orange.demo.gateway.constant;
* 网关业务相关的常量对象。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
public final class GatewayConstant {

View File

@@ -12,7 +12,6 @@ import com.orange.demo.common.core.util.RedisKeyUtil;
import com.orange.demo.gateway.config.ApplicationConfig;
import com.orange.demo.gateway.constant.GatewayConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
@@ -46,7 +45,7 @@ import java.util.Map;
* 全局后处理过滤器。主要用于将用户的会话信息存到缓存服务器,以及在登出时清除缓存中的会话数据。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Slf4j
public class AuthenticationPostFilter implements GlobalFilter, Ordered {
@@ -235,21 +234,12 @@ public class AuthenticationPostFilter implements GlobalFilter, Ordered {
}
t.exec();
}
// 4. 构造返回给用户的应答
JSONObject resultJsonData = new JSONObject();
resultJsonData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token);
resultJsonData.put("isAdmin", isAdmin);
resultJsonData.put("showName", showName);
JSONArray menuList = loginData.getJSONArray("menuList");
if (CollectionUtils.isNotEmpty(menuList)) {
resultJsonData.put("menuList", menuList);
// 4. 构造返回给用户的应答,将加密后的令牌返回给前端。
loginData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token);
// 如果是管理员,不用返回权限字列表。
if (Boolean.TRUE.equals(isAdmin)) {
loginData.remove("permCodeList");
}
if (Boolean.FALSE.equals(isAdmin)) {
JSONArray permCodeList = loginData.getJSONArray("permCodeList");
if (CollectionUtils.isNotEmpty(permCodeList)) {
resultJsonData.put("permCodeList", permCodeList);
}
}
return ResponseResult.success(resultJsonData);
return ResponseResult.success(loginData);
}
}

View File

@@ -12,6 +12,7 @@ import com.orange.demo.gateway.config.ApplicationConfig;
import com.orange.demo.gateway.constant.GatewayConstant;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
@@ -21,6 +22,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -30,15 +32,13 @@ import redis.clients.jedis.JedisPool;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 全局前处理过滤器。主要用于用户操作权限验证。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Slf4j
public class AuthenticationPreFilter implements GlobalFilter, Ordered {
@@ -47,20 +47,18 @@ public class AuthenticationPreFilter implements GlobalFilter, Ordered {
private ApplicationConfig appConfig;
@Autowired
private JedisPool jedisPool;
private static List<String> whitelistUrlPattern = new LinkedList<>();
static {
// 这里可以添加URL部分匹配的白名单列表
// 另外解释一下数据库中配置的白名单列表在doLogin中直接合并到当前用户的权限列表中了。
}
/**
* Ant Pattern模式的白名单地址匹配器。
*/
private AntPathMatcher antMatcher = new AntPathMatcher();
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String url = request.getURI().getPath();
// 登录请求直接转发给login验证服务器
if (url.equals(GatewayConstant.ADMIN_LOGIN_URL)) {
// 判断是否为白名单请求,以及一些内置不需要验证的请求。(登录请求也包含其中)
if (this.shouldNotFilter(url)) {
return chain.filter(exchange);
}
String token = this.getTokenFromRequest(request);
@@ -155,15 +153,37 @@ public class AuthenticationPreFilter implements GlobalFilter, Ordered {
private boolean hasPermission(Jedis jedis, String sessionId, String url) {
// 对于退出登录操作,不需要进行权限验证,仅仅确认是已经登录的合法用户即可。
if (url.equals(GatewayConstant.ADMIN_LOGOUT_URL)
|| Boolean.TRUE.equals(jedis.sismember(RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId), url))) {
return url.equals(GatewayConstant.ADMIN_LOGOUT_URL)
|| Boolean.TRUE.equals(jedis.sismember(RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId), url));
}
/**
* 判断当前请求的url是否为配置中的白名单地址。以及一些内置的不需要登录即可访问的url。
* @param url 请求的url。
* @return 是返回true否则false。
*/
private boolean shouldNotFilter(String url) {
// 这里过滤和swagger相关的url
if (url.endsWith("/v2/api-docs") || url.endsWith("/v2/api-docs-ext")) {
return true;
}
for (String urlPattern : whitelistUrlPattern) {
if (url.startsWith(urlPattern)) {
if (url.equals(GatewayConstant.ADMIN_LOGIN_URL)) {
return true;
}
// 先过滤直接匹配的白名单url。
if (CollectionUtils.isNotEmpty(appConfig.getWhitelistUrl())) {
if (appConfig.getWhitelistUrl().contains(url)) {
return true;
}
}
// 过滤ant pattern模式的白名单url。
if (CollectionUtils.isNotEmpty(appConfig.getWhitelistUrlPattern())) {
for (String urlPattern : appConfig.getWhitelistUrlPattern()) {
if (antMatcher.match(urlPattern, url)) {
return true;
}
}
}
return false;
}
}

View File

@@ -17,7 +17,7 @@ import reactor.core.publisher.Mono;
* 为整个链路生成唯一的traceId并存储在Request Head中。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Slf4j
public class RequestLogFilter implements GlobalFilter, Ordered {

View File

@@ -16,7 +16,7 @@ import reactor.core.publisher.Mono;
* 将整个链路的traceId存储在Response Head中并返回给前端便于问题定位。
*
* @author Jerry
* @date 2020-10-19
* @date 2020-08-08
*/
@Slf4j
public class ResponseLogFilter implements GlobalFilter, Ordered {

View File

@@ -0,0 +1,53 @@
package com.orange.demo.gateway.handler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;
import java.util.Optional;
/**
* Swagger的资源请求处理器。
*
* @author Knife4j Team。
* @date 2020-08-08
*/
@RestController
public class SwaggerHandler {
@Autowired(required = false)
private SecurityConfiguration securityConfiguration;
@Autowired(required = false)
private UiConfiguration uiConfiguration;
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
@GetMapping("/swagger-resources/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration)
.orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("/swagger-resources/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration)
.orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("/swagger-resources")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}

View File

@@ -59,6 +59,9 @@
<Root level="${OUTPUT_LOG_LEVEL}">
<AppenderRef ref="console"/>
</Root>
<Logger name="springfox.documentation" additivity="false" level="error">
<AppenderRef ref="console"/>
</Logger>
<!-- AsyncLogger 是基于Disruptor的全量异步队列性能极高队列默认大小4096。-->
<!-- 队列默认值可通过JVM参数设置参考博客https://www.jianshu.com/p/82469047acbf -->
<AsyncLogger name="com.orange.demo" additivity="false" level="info">