|
|
@@ -0,0 +1,194 @@
|
|
|
+package com.dk.gateway.oauth.filter;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.dk.gateway.enums.ErrorCodeEnum;
|
|
|
+import com.dk.gateway.oauth.util.AESSecurityUtil;
|
|
|
+import com.dk.gateway.oauth.util.JwtUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+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.data.redis.core.StringRedisTemplate;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.http.server.reactive.ServerHttpResponse;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.server.ServerWebExchange;
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class Oauth2Filter implements GlobalFilter, Ordered {
|
|
|
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
|
+
|
|
|
+ // token校验跳过的url,多个url用";"号隔开
|
|
|
+ @Value("${filterPath}")
|
|
|
+ private String filterPath;
|
|
|
+ @Value("${mdmFilterPath}")
|
|
|
+ private String mdmFilterPath;
|
|
|
+ @Value("${aes-key}")
|
|
|
+ private String AESKey;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private StringRedisTemplate stringRedisTemplate;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getOrder() {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
|
|
+ ServerHttpResponse response = exchange.getResponse();
|
|
|
+ // 过滤掉不需要进行权限控制的服务
|
|
|
+ String path = exchange.getRequest().getPath().toString();
|
|
|
+ logger.info("-------请求地址----{}", path);
|
|
|
+ String[] filterPaths = filterPath.split(";");
|
|
|
+ if (Arrays.asList(filterPaths).contains(path)) {
|
|
|
+ logger.info("------不需要权限----{}", path);
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ if (path.contains("/wxapi")) {
|
|
|
+ logger.info("------小程序接口----{}", path);
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ if (path.contains("/druid")) {
|
|
|
+ logger.info("------druid接口----{}", path);
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ if (path.contains("/scheduler-server")) {
|
|
|
+ logger.info("------定时任务接口----{}", path);
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ if (path.contains("/export")) {
|
|
|
+ logger.info("------export接口----{}" + path);
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ //todo
|
|
|
+ String[] mdmFilterPaths = mdmFilterPath.split(";");
|
|
|
+ if(mdmFilterPaths != null && mdmFilterPaths.length > 0 && path != null ){
|
|
|
+ String tempPath = path.substring(1);
|
|
|
+ tempPath = tempPath.substring(tempPath.indexOf("/"));
|
|
|
+ if (Arrays.asList(mdmFilterPaths).contains(tempPath)) {
|
|
|
+ logger.info("------不需要权限----{}", path);
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 获取token
|
|
|
+ String accessToken = exchange.getRequest().getHeaders().getFirst("Authorization");
|
|
|
+ String decodedAccessToken = accessToken;
|
|
|
+ logger.info("------获取的token----{}", decodedAccessToken);
|
|
|
+
|
|
|
+ if (accessToken != null) {
|
|
|
+ String[] tokens = accessToken.split(" ");
|
|
|
+ try {
|
|
|
+ String decrypt = AESSecurityUtil.decrypt(AESKey, tokens[1]);
|
|
|
+ String userId = JwtUtil.getUserId(decrypt);
|
|
|
+ String appCode = JwtUtil.getAppCode(decrypt);
|
|
|
+ String mapJson = stringRedisTemplate.opsForValue().get("REDIS_USER_LOGIN_" + userId + "_" + appCode);
|
|
|
+ Map<String, Object> userMap = JSON.parseObject(mapJson);
|
|
|
+ String token = "Bearer " + userMap.get("accessToken");
|
|
|
+ if (!accessToken.equals(token) ) {
|
|
|
+ //定义响应体
|
|
|
+ JSONObject result = new JSONObject() {{
|
|
|
+ put("code", ErrorCodeEnum.USER_TOKEN_EXPIRE.getCode());
|
|
|
+ put("message", ErrorCodeEnum.USER_TOKEN_EXPIRE.getMessage());
|
|
|
+ put("data", "");
|
|
|
+ }};
|
|
|
+ //作JSON转换
|
|
|
+ byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
|
|
|
+ //调用bufferFactory方法,生成DataBuffer对象
|
|
|
+ DataBuffer buffer = response.bufferFactory().wrap(bytes);
|
|
|
+ //调用Mono中的just方法,返回要写给前端的JSON数据
|
|
|
+ return response.writeWith(Mono.just(buffer));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String jwt = null;
|
|
|
+ String userName = null;
|
|
|
+
|
|
|
+// if (StringUtils.isNotBlank(decodedAccessToken)) {
|
|
|
+// String[] tokens = decodedAccessToken.split(" ");
|
|
|
+// // 验证Access Token
|
|
|
+// logger.info("encode token ------->>>>{}", tokens[1]);
|
|
|
+// try {
|
|
|
+// // TOKEN反解密
|
|
|
+// jwt = AESSecurityUtil.decrypt(AESKey, tokens[1]);
|
|
|
+// decodedAccessToken = tokens[0] + " " + jwt;
|
|
|
+// logger.info("decode Token: {}", decodedAccessToken);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error("error message: {}", e.getMessage());
|
|
|
+// logger.error("sorry,accessToken({}),decode faild!", tokens[1]);
|
|
|
+// }
|
|
|
+// // 判断
|
|
|
+// if (StringUtils.isBlank(jwt)) {
|
|
|
+// logger.error("JWT 变量为空.");
|
|
|
+// } else {
|
|
|
+// userName = JwtUtil.getUserName(jwt);
|
|
|
+// }
|
|
|
+// // TOKEN校验
|
|
|
+// if (!JwtUtil.verify(jwt, userName)) {
|
|
|
+// // 如果不存在/过期了,返回未验证错误,需重新验证
|
|
|
+// logger.info("------token过期----{}" , decodedAccessToken);
|
|
|
+// // 定义响应头部信息
|
|
|
+// response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
|
|
+// response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
|
|
+//
|
|
|
+// //定义响应体
|
|
|
+// JSONObject result = new JSONObject(){{
|
|
|
+// put("code",1002);
|
|
|
+// put("message","用户令牌已过期,请重新登录");
|
|
|
+// put("data","");
|
|
|
+// }};
|
|
|
+//
|
|
|
+// //作JSON转换
|
|
|
+// byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
|
|
|
+//
|
|
|
+// //调用bufferFactory方法,生成DataBuffer对象
|
|
|
+// DataBuffer buffer = response.bufferFactory().wrap(bytes);
|
|
|
+//
|
|
|
+// //调用Mono中的just方法,返回要写给前端的JSON数据
|
|
|
+// return response.writeWith(Mono.just(buffer));
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// logger.info("------token为空----{}" , decodedAccessToken);
|
|
|
+// // 定义响应头部信息
|
|
|
+// response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
|
|
+// response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
|
|
+//
|
|
|
+// //定义响应体
|
|
|
+// JSONObject result = new JSONObject(){{
|
|
|
+// put("code",1000);
|
|
|
+// put("message","用户令牌为空,请重新登录");
|
|
|
+// put("data","");
|
|
|
+// }};
|
|
|
+//
|
|
|
+// //作JSON转换
|
|
|
+// byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
|
|
|
+//
|
|
|
+// //调用bufferFactory方法,生成DataBuffer对象
|
|
|
+// DataBuffer buffer = response.bufferFactory().wrap(bytes);
|
|
|
+//
|
|
|
+// //调用Mono中的just方法,返回要写给前端的JSON数据
|
|
|
+// return response.writeWith(Mono.just(buffer));
|
|
|
+// }
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|