diff --git a/blade-gateway/pom.xml b/blade-gateway/pom.xml
index 89dfd6a3..8760d1c6 100644
--- a/blade-gateway/pom.xml
+++ b/blade-gateway/pom.xml
@@ -42,6 +42,11 @@
+
+ org.springblade
+ blade-starter-jwt
+ ${bladex.project.version}
+
org.springframework.cloud
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/config/RouterFunctionConfiguration.java b/blade-gateway/src/main/java/org/springblade/gateway/config/RouterFunctionConfiguration.java
index 470ebf44..1f926abb 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/config/RouterFunctionConfiguration.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/config/RouterFunctionConfiguration.java
@@ -19,6 +19,7 @@ package org.springblade.gateway.config;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.gateway.handler.SwaggerResourceHandler;
+import org.springblade.gateway.props.AuthProperties;
import org.springblade.gateway.props.RouteProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -40,7 +41,7 @@ import reactor.core.publisher.Mono;
@Slf4j
@Configuration
@AllArgsConstructor
-@EnableConfigurationProperties(RouteProperties.class)
+@EnableConfigurationProperties({RouteProperties.class, AuthProperties.class})
public class RouterFunctionConfiguration {
private final SwaggerResourceHandler swaggerResourceHandler;
@@ -48,12 +49,12 @@ public class RouterFunctionConfiguration {
@Bean
public RouterFunction routerFunction() {
return RouterFunctions.route(RequestPredicates.GET("/swagger-resources")
- .and(RequestPredicates.accept(MediaType.ALL)), swaggerResourceHandler);
+ .and(RequestPredicates.accept(MediaType.ALL)), swaggerResourceHandler);
}
/**
- * 解决springboot2.0.5版本出现的 Only one connection receive subscriber allowed.
+ * 解决 Only one connection receive subscriber allowed.
* 参考:https://github.com/spring-cloud/spring-cloud-gateway/issues/541
*/
@Bean
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/service/DynamicRouteService.java b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/DynamicRouteService.java
similarity index 98%
rename from blade-gateway/src/main/java/org/springblade/gateway/dynamic/service/DynamicRouteService.java
rename to blade-gateway/src/main/java/org/springblade/gateway/dynamic/DynamicRouteService.java
index 363ada95..aed779ad 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/service/DynamicRouteService.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/DynamicRouteService.java
@@ -14,7 +14,7 @@
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
-package org.springblade.gateway.dynamic.service;
+package org.springblade.gateway.dynamic;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/service/DynamicRouteServiceListener.java b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/DynamicRouteServiceListener.java
similarity index 98%
rename from blade-gateway/src/main/java/org/springblade/gateway/dynamic/service/DynamicRouteServiceListener.java
rename to blade-gateway/src/main/java/org/springblade/gateway/dynamic/DynamicRouteServiceListener.java
index 95af9cc6..e7996bc3 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/service/DynamicRouteServiceListener.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/DynamicRouteServiceListener.java
@@ -14,7 +14,7 @@
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
-package org.springblade.gateway.dynamic.service;
+package org.springblade.gateway.dynamic;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayFilter.java b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayFilter.java
similarity index 96%
rename from blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayFilter.java
rename to blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayFilter.java
index b224c683..a7c64ec8 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayFilter.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayFilter.java
@@ -14,7 +14,7 @@
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
-package org.springblade.gateway.dynamic.model;
+package org.springblade.gateway.dynamic;
import lombok.Data;
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayPredicate.java b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayPredicate.java
similarity index 96%
rename from blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayPredicate.java
rename to blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayPredicate.java
index 0c53a293..1e8e4351 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayPredicate.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayPredicate.java
@@ -14,7 +14,7 @@
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
-package org.springblade.gateway.dynamic.model;
+package org.springblade.gateway.dynamic;
import lombok.Data;
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayRoute.java b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayRoute.java
similarity index 96%
rename from blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayRoute.java
rename to blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayRoute.java
index a9b6ff61..c1260093 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/dynamic/model/GatewayRoute.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/dynamic/GatewayRoute.java
@@ -14,7 +14,7 @@
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
-package org.springblade.gateway.dynamic.model;
+package org.springblade.gateway.dynamic;
import lombok.Data;
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/endpoint/RouteEndpoint.java b/blade-gateway/src/main/java/org/springblade/gateway/endpoint/RouteEndpoint.java
index 4b49902b..4e811561 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/endpoint/RouteEndpoint.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/endpoint/RouteEndpoint.java
@@ -17,9 +17,9 @@
package org.springblade.gateway.endpoint;
import lombok.AllArgsConstructor;
-import org.springblade.gateway.dynamic.model.GatewayPredicate;
-import org.springblade.gateway.dynamic.model.GatewayRoute;
-import org.springblade.gateway.dynamic.service.DynamicRouteService;
+import org.springblade.gateway.dynamic.GatewayPredicate;
+import org.springblade.gateway.dynamic.GatewayRoute;
+import org.springblade.gateway.dynamic.DynamicRouteService;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java b/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java
new file mode 100644
index 00000000..c9d4fed8
--- /dev/null
+++ b/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.gateway.filter;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.jsonwebtoken.Claims;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springblade.core.jwt.JwtUtil;
+import org.springblade.gateway.props.AuthProperties;
+import org.springblade.gateway.provider.AuthProvider;
+import org.springblade.gateway.provider.ResponseProvider;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鉴权认证
+ *
+ * @author Chill
+ */
+@Slf4j
+@Component
+@AllArgsConstructor
+public class AuthFilter implements GlobalFilter, Ordered {
+ private AuthProperties authProperties;
+ private ObjectMapper objectMapper;
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ String path = exchange.getRequest().getURI().getPath();
+ if (isSkip(path)) {
+ return chain.filter(exchange);
+ }
+ ServerHttpResponse resp = exchange.getResponse();
+ String headerToken = exchange.getRequest().getHeaders().getFirst(AuthProvider.AUTH_HEADER);
+ String paramToken = exchange.getRequest().getQueryParams().getFirst(AuthProvider.AUTH_HEADER);
+ if (StringUtils.isAllBlank(headerToken, paramToken)) {
+ return unAuth(resp, "缺失令牌,鉴权失败");
+ }
+ String auth = StringUtils.isBlank(headerToken) ? paramToken : headerToken;
+ String token = JwtUtil.getToken(auth);
+ Claims claims = JwtUtil.parseJWT(token);
+ if (claims == null) {
+ return unAuth(resp, "请求未授权");
+ }
+ return chain.filter(exchange);
+ }
+
+ private boolean isSkip(String path) {
+ return AuthProvider.getDefaultSkipUrl().stream().map(url -> url.replace(AuthProvider.TARGET, AuthProvider.REPLACEMENT)).anyMatch(path::startsWith)
+ || authProperties.getSkipUrl().stream().map(url -> url.replace(AuthProvider.TARGET, AuthProvider.REPLACEMENT)).anyMatch(path::startsWith);
+ }
+
+ private Mono unAuth(ServerHttpResponse resp, String msg) {
+ resp.setStatusCode(HttpStatus.UNAUTHORIZED);
+ resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
+ String result = "";
+ try {
+ result = objectMapper.writeValueAsString(ResponseProvider.unAuth(msg));
+ } catch (JsonProcessingException e) {
+ log.error(e.getMessage(), e);
+ }
+ DataBuffer buffer = resp.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
+ return resp.writeWith(Flux.just(buffer));
+ }
+
+ @Override
+ public int getOrder() {
+ return -100;
+ }
+
+}
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/filter/RequestGlobalFilter.java b/blade-gateway/src/main/java/org/springblade/gateway/filter/RequestFilter.java
similarity index 96%
rename from blade-gateway/src/main/java/org/springblade/gateway/filter/RequestGlobalFilter.java
rename to blade-gateway/src/main/java/org/springblade/gateway/filter/RequestFilter.java
index b3af9d9f..b351716c 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/filter/RequestGlobalFilter.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/filter/RequestFilter.java
@@ -25,7 +25,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.a
* @author lengleng
*/
@Component
-public class RequestGlobalFilter implements GlobalFilter, Ordered {
+public class RequestFilter implements GlobalFilter, Ordered {
/**
* Process the Web request and (optionally) delegate to the next
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/handler/ErrorExceptionHandler.java b/blade-gateway/src/main/java/org/springblade/gateway/handler/ErrorExceptionHandler.java
index 0baa2cbb..282ab0c7 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/handler/ErrorExceptionHandler.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/handler/ErrorExceptionHandler.java
@@ -16,6 +16,7 @@
*/
package org.springblade.gateway.handler;
+import org.springblade.gateway.provider.ResponseProvider;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
@@ -26,7 +27,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.*;
import org.springframework.web.server.ResponseStatusException;
-import java.util.HashMap;
import java.util.Map;
/**
@@ -54,7 +54,7 @@ public class ErrorExceptionHandler extends DefaultErrorWebExceptionHandler {
if (error instanceof ResponseStatusException) {
code = ((ResponseStatusException) error).getStatus().value();
}
- return response(code, this.buildMessage(request, error));
+ return ResponseProvider.response(code, this.buildMessage(request, error));
}
/**
@@ -98,19 +98,4 @@ public class ErrorExceptionHandler extends DefaultErrorWebExceptionHandler {
return message.toString();
}
- /**
- * 构建返回的JSON数据格式
- *
- * @param status 状态码
- * @param errorMessage 异常信息
- * @return
- */
- public static Map response(int status, String errorMessage) {
- Map map = new HashMap<>(16);
- map.put("code", status);
- map.put("message", errorMessage);
- map.put("data", null);
- return map;
- }
-
}
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/props/AuthProperties.java b/blade-gateway/src/main/java/org/springblade/gateway/props/AuthProperties.java
new file mode 100644
index 00000000..c0908a76
--- /dev/null
+++ b/blade-gateway/src/main/java/org/springblade/gateway/props/AuthProperties.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.gateway.props;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 权限过滤
+ *
+ * @author Chill
+ */
+@Data
+@ConfigurationProperties("blade.secure")
+public class AuthProperties {
+
+ private final List skipUrl = new ArrayList<>();
+
+}
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java b/blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
new file mode 100644
index 00000000..5a7b53dc
--- /dev/null
+++ b/blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.gateway.provider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鉴权配置
+ *
+ * @author Chill
+ */
+public class AuthProvider {
+
+ public static String TARGET = "/**";
+ public static String REPLACEMENT = "";
+ public static String AUTH_HEADER = "Blade-Auth";
+ private static List defaultSkipUrl = new ArrayList<>();
+
+ static {
+ defaultSkipUrl.add("/client/**");
+ defaultSkipUrl.add("/oauth/token/**");
+ defaultSkipUrl.add("/token/**");
+ defaultSkipUrl.add("/actuator/health/**");
+ defaultSkipUrl.add("/v2/api-docs/**");
+ defaultSkipUrl.add("/v2/api-docs-ext/**");
+ defaultSkipUrl.add("/auth/**");
+ defaultSkipUrl.add("/log/**");
+ defaultSkipUrl.add("/menu/routes");
+ defaultSkipUrl.add("/menu/auth-routes");
+ defaultSkipUrl.add("/menu/top-menu");
+ defaultSkipUrl.add("/process/resource-view");
+ defaultSkipUrl.add("/process/diagram-view");
+ defaultSkipUrl.add("/manager/check-upload");
+ defaultSkipUrl.add("/error/**");
+ defaultSkipUrl.add("/assets/**");
+ }
+
+ /**
+ * 默认无需鉴权的API
+ */
+ public static List getDefaultSkipUrl() {
+ return defaultSkipUrl;
+ }
+
+}
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/provider/ResponseProvider.java b/blade-gateway/src/main/java/org/springblade/gateway/provider/ResponseProvider.java
new file mode 100644
index 00000000..38f8efb6
--- /dev/null
+++ b/blade-gateway/src/main/java/org/springblade/gateway/provider/ResponseProvider.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.gateway.provider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 请求响应返回
+ *
+ * @author Chill
+ */
+public class ResponseProvider {
+
+ /**
+ * 成功
+ *
+ * @param message 信息
+ * @return
+ */
+ public static Map success(String message) {
+ return response(200, message);
+ }
+
+ /**
+ * 失败
+ *
+ * @param message 信息
+ * @return
+ */
+ public static Map fail(String message) {
+ return response(400, message);
+ }
+
+ /**
+ * 未授权
+ *
+ * @param message 信息
+ * @return
+ */
+ public static Map unAuth(String message) {
+ return response(401, message);
+ }
+
+ /**
+ * 服务器异常
+ *
+ * @param message 信息
+ * @return
+ */
+ public static Map error(String message) {
+ return response(500, message);
+ }
+
+ /**
+ * 构建返回的JSON数据格式
+ *
+ * @param status 状态码
+ * @param message 信息
+ * @return
+ */
+ public static Map response(int status, String message) {
+ Map map = new HashMap<>(16);
+ map.put("code", status);
+ map.put("message", message);
+ map.put("data", null);
+ return map;
+ }
+
+}
diff --git a/blade-gateway/src/main/java/org/springblade/gateway/provider/SwaggerProvider.java b/blade-gateway/src/main/java/org/springblade/gateway/provider/SwaggerProvider.java
index a6031b20..098b1286 100644
--- a/blade-gateway/src/main/java/org/springblade/gateway/provider/SwaggerProvider.java
+++ b/blade-gateway/src/main/java/org/springblade/gateway/provider/SwaggerProvider.java
@@ -14,7 +14,6 @@
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
-
package org.springblade.gateway.provider;
import lombok.AllArgsConstructor;
diff --git a/doc/nacos/blade.yaml b/doc/nacos/blade.yaml
index 9c7ccbf6..fa79590a 100644
--- a/doc/nacos/blade.yaml
+++ b/doc/nacos/blade.yaml
@@ -69,14 +69,12 @@ management:
#blade配置
blade:
xss:
- url:
- exclude-patterns:
- - /weixin
- - /notice/submit
+ skip-url:
+ - /weixin
+ - /notice/submit
secure:
- url:
- exclude-patterns:
- - /test/**
+ skip-url:
+ - /test/**
client:
- client-id: sword
path-patterns: