diff --git a/README.md b/README.md index 3f7d661..4570768 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- Downloads + Downloads Build Status Build Status Coverage Status diff --git a/blade-auth/pom.xml b/blade-auth/pom.xml index cdb7c28..4b1245e 100644 --- a/blade-auth/pom.xml +++ b/blade-auth/pom.xml @@ -8,7 +8,7 @@ SpringBlade org.springblade - 2.5.0 + 2.5.1 blade-auth diff --git a/blade-common/pom.xml b/blade-common/pom.xml index b85b5a6..b79bcd0 100644 --- a/blade-common/pom.xml +++ b/blade-common/pom.xml @@ -5,7 +5,7 @@ SpringBlade org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-gateway/pom.xml b/blade-gateway/pom.xml index 40300e5..eab0b19 100644 --- a/blade-gateway/pom.xml +++ b/blade-gateway/pom.xml @@ -5,7 +5,7 @@ SpringBlade org.springblade - 2.5.0 + 2.5.1 4.0.0 @@ -77,6 +77,12 @@ spring-cloud-starter-alibaba-nacos-config ${alibaba.cloud.version} + + + io.jsonwebtoken + jjwt + 0.9.1 + io.springfox 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 e365667..f205866 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,7 +49,7 @@ 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); } 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 0000000..47adfae --- /dev/null +++ b/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 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.gateway.props.AuthProperties; +import org.springblade.gateway.provider.AuthProvider; +import org.springblade.gateway.provider.ResponseProvider; +import org.springblade.gateway.utils.JwtUtil; +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_KEY); + String paramToken = exchange.getRequest().getQueryParams().getFirst(AuthProvider.AUTH_KEY); + 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::contains) + || authProperties.getSkipUrl().stream().map(url -> url.replace(AuthProvider.TARGET, AuthProvider.REPLACEMENT)).anyMatch(path::contains); + } + + 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/handler/ErrorExceptionHandler.java b/blade-gateway/src/main/java/org/springblade/gateway/handler/ErrorExceptionHandler.java index 0d93328..de28f2b 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 @@ -15,6 +15,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; @@ -25,7 +26,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; /** @@ -53,7 +53,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)); } /** @@ -97,19 +97,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 0000000..efb8d54 --- /dev/null +++ b/blade-gateway/src/main/java/org/springblade/gateway/props/AuthProperties.java @@ -0,0 +1,41 @@ +/* + * 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 org.springframework.cloud.context.config.annotation.RefreshScope; + +import java.util.ArrayList; +import java.util.List; + +/** + * 权限过滤 + * + * @author Chill + */ +@Data +@RefreshScope +@ConfigurationProperties("blade.secure") +public class AuthProperties { + + /** + * 放行API集合 + */ + 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 0000000..4fa3a10 --- /dev/null +++ b/blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 org.springblade.gateway.provider; + +import org.springblade.core.launch.constant.TokenConstant; + +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_KEY = TokenConstant.HEADER; + private static List defaultSkipUrl = new ArrayList<>(); + + static { + defaultSkipUrl.add("/example"); + 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("/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 0000000..cf4eb42 --- /dev/null +++ b/blade-gateway/src/main/java/org/springblade/gateway/provider/ResponseProvider.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 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/utils/JwtUtil.java b/blade-gateway/src/main/java/org/springblade/gateway/utils/JwtUtil.java new file mode 100644 index 0000000..c422fc3 --- /dev/null +++ b/blade-gateway/src/main/java/org/springblade/gateway/utils/JwtUtil.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 org.springblade.gateway.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +/** + * JwtUtil + * + * @author Chill + */ +public class JwtUtil { + + public static String SIGN_KEY = "BladeX"; + public static String BEARER = "bearer"; + public static Integer AUTH_LENGTH = 7; + + public static String BASE64_SECURITY = Base64.getEncoder().encodeToString(SIGN_KEY.getBytes(StandardCharsets.UTF_8)); + + /** + * 获取token串 + * + * @param auth token + * @return String + */ + public static String getToken(String auth) { + if ((auth != null) && (auth.length() > AUTH_LENGTH)) { + String headStr = auth.substring(0, 6).toLowerCase(); + if (headStr.compareTo(BEARER) == 0) { + auth = auth.substring(7); + return auth; + } + } + return null; + } + + /** + * 解析jsonWebToken + * + * @param jsonWebToken token串 + * @return Claims + */ + public static Claims parseJWT(String jsonWebToken) { + try { + return Jwts.parser() + .setSigningKey(Base64.getDecoder().decode(JwtUtil.BASE64_SECURITY)) + .parseClaimsJws(jsonWebToken).getBody(); + } catch (Exception ex) { + return null; + } + } + +} diff --git a/blade-ops/blade-admin/pom.xml b/blade-ops/blade-admin/pom.xml index 0668acc..6eeedc1 100644 --- a/blade-ops/blade-admin/pom.xml +++ b/blade-ops/blade-admin/pom.xml @@ -5,7 +5,7 @@ blade-ops org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-ops/blade-develop/pom.xml b/blade-ops/blade-develop/pom.xml index 18df48e..634fa59 100644 --- a/blade-ops/blade-develop/pom.xml +++ b/blade-ops/blade-develop/pom.xml @@ -6,7 +6,7 @@ org.springblade blade-ops - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-ops/blade-resource/pom.xml b/blade-ops/blade-resource/pom.xml index 0d18d22..0435fb5 100644 --- a/blade-ops/blade-resource/pom.xml +++ b/blade-ops/blade-resource/pom.xml @@ -5,7 +5,7 @@ blade-ops org.springblade - 2.5.0 + 2.5.1 4.0.0 @@ -29,6 +29,12 @@ org.springblade blade-core-cloud ${blade.tool.version} + + + org.springblade + blade-core-secure + + org.springblade diff --git a/blade-ops/blade-seata-order/pom.xml b/blade-ops/blade-seata-order/pom.xml index efe6d37..53f4bf3 100644 --- a/blade-ops/blade-seata-order/pom.xml +++ b/blade-ops/blade-seata-order/pom.xml @@ -5,7 +5,7 @@ blade-ops org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-ops/blade-seata-storage/pom.xml b/blade-ops/blade-seata-storage/pom.xml index c350b31..433f8ac 100644 --- a/blade-ops/blade-seata-storage/pom.xml +++ b/blade-ops/blade-seata-storage/pom.xml @@ -5,7 +5,7 @@ blade-ops org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-ops/pom.xml b/blade-ops/pom.xml index ac572c0..d567efb 100644 --- a/blade-ops/pom.xml +++ b/blade-ops/pom.xml @@ -5,7 +5,7 @@ SpringBlade org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service-api/blade-desk-api/pom.xml b/blade-service-api/blade-desk-api/pom.xml index e346057..0608f4c 100644 --- a/blade-service-api/blade-desk-api/pom.xml +++ b/blade-service-api/blade-desk-api/pom.xml @@ -5,7 +5,7 @@ blade-service-api org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service-api/blade-dict-api/pom.xml b/blade-service-api/blade-dict-api/pom.xml index 3d794f7..5a6b3db 100644 --- a/blade-service-api/blade-dict-api/pom.xml +++ b/blade-service-api/blade-dict-api/pom.xml @@ -5,7 +5,7 @@ blade-service-api org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service-api/blade-system-api/pom.xml b/blade-service-api/blade-system-api/pom.xml index 38b1753..651735b 100644 --- a/blade-service-api/blade-system-api/pom.xml +++ b/blade-service-api/blade-system-api/pom.xml @@ -5,7 +5,7 @@ blade-service-api org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service-api/blade-user-api/pom.xml b/blade-service-api/blade-user-api/pom.xml index d034221..bc2d0c8 100644 --- a/blade-service-api/blade-user-api/pom.xml +++ b/blade-service-api/blade-user-api/pom.xml @@ -5,7 +5,7 @@ blade-service-api org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service-api/pom.xml b/blade-service-api/pom.xml index 04dbac8..25add24 100644 --- a/blade-service-api/pom.xml +++ b/blade-service-api/pom.xml @@ -5,13 +5,13 @@ SpringBlade org.springblade - 2.5.0 + 2.5.1 4.0.0 blade-service-api ${project.artifactId} - 2.5.0 + 2.5.1 pom SpringBlade 微服务API集合 diff --git a/blade-service/blade-desk/pom.xml b/blade-service/blade-desk/pom.xml index f4f5ec3..de71b86 100644 --- a/blade-service/blade-desk/pom.xml +++ b/blade-service/blade-desk/pom.xml @@ -6,7 +6,7 @@ org.springblade blade-service - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service/blade-log/pom.xml b/blade-service/blade-log/pom.xml index 3195d8f..423f5ce 100644 --- a/blade-service/blade-log/pom.xml +++ b/blade-service/blade-log/pom.xml @@ -5,7 +5,7 @@ blade-service org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service/blade-system/pom.xml b/blade-service/blade-system/pom.xml index 8b7a671..006c984 100644 --- a/blade-service/blade-system/pom.xml +++ b/blade-service/blade-system/pom.xml @@ -5,7 +5,7 @@ blade-service org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service/blade-user/pom.xml b/blade-service/blade-user/pom.xml index 6047d7d..f092fa4 100644 --- a/blade-service/blade-user/pom.xml +++ b/blade-service/blade-user/pom.xml @@ -5,7 +5,7 @@ blade-service org.springblade - 2.5.0 + 2.5.1 4.0.0 diff --git a/blade-service/pom.xml b/blade-service/pom.xml index 7946e6e..c95761f 100644 --- a/blade-service/pom.xml +++ b/blade-service/pom.xml @@ -7,12 +7,12 @@ org.springblade SpringBlade - 2.5.0 + 2.5.1 blade-service ${project.artifactId} - 2.5.0 + 2.5.1 pom SpringBlade 微服务集合 diff --git a/pom.xml b/pom.xml index c96bcf8..1986ef9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ org.springblade SpringBlade - 2.5.0 + 2.5.1 pom - 2.5.0 - 2.5.0 + 2.5.1 + 2.5.1 1.8 2.9.2 diff --git a/script/docker/.env b/script/docker/.env index b109b62..cc81ca8 100644 --- a/script/docker/.env +++ b/script/docker/.env @@ -1,2 +1,2 @@ REGISTER=192.168.0.157/blade -TAG=2.5.0 +TAG=2.5.1 diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index f776423..1a50537 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: nacos: - image: nacos/nacos-server:0.9.0 + image: nacos/nacos-server:1.1.3 hostname: "nacos-standalone" environment: - MODE=standalone