|
@@ -0,0 +1,174 @@
|
|
|
+package com.fdkankan.gateway.filter;
|
|
|
+
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.fdkankan.common.constant.RedisKey;
|
|
|
+import com.fdkankan.common.constant.ServerCode;
|
|
|
+import com.fdkankan.common.response.ResultData;
|
|
|
+import com.fdkankan.common.util.JwtUtil;
|
|
|
+import io.jsonwebtoken.Claims;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+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.RedisTemplate;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.http.server.reactive.ServerHttpRequest;
|
|
|
+import org.springframework.http.server.reactive.ServerHttpResponse;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.server.ServerWebExchange;
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class TokenFilter implements GlobalFilter, Ordered {
|
|
|
+
|
|
|
+ private static final String TOKEN = "token";
|
|
|
+
|
|
|
+ private static final Map<String, List<String>> permissionMap = new HashMap<>();
|
|
|
+
|
|
|
+ private static final List<String> ignoreAuthUrls = new ArrayList<>();
|
|
|
+
|
|
|
+// @Resource
|
|
|
+// private RedisUtil redisUtil;
|
|
|
+ @Autowired
|
|
|
+ private RedisTemplate<String, String> redisTemplate;
|
|
|
+
|
|
|
+ static {
|
|
|
+ List<String> userPermissions = new ArrayList<>();
|
|
|
+ permissionMap.put("user", userPermissions);
|
|
|
+ userPermissions.add("/api/user");
|
|
|
+ userPermissions.add("/api/scene/edit");
|
|
|
+ userPermissions.add("/api/scene/edit");
|
|
|
+ userPermissions.add("/api/order/scanPay");
|
|
|
+
|
|
|
+ List<String> managerPermissions = new ArrayList<>();
|
|
|
+ permissionMap.put("manager", managerPermissions);
|
|
|
+ userPermissions.add("/api/manager");
|
|
|
+
|
|
|
+ List<String> agentPermissions = new ArrayList<>();
|
|
|
+ permissionMap.put("agent", agentPermissions);
|
|
|
+ userPermissions.add("/api/agent");
|
|
|
+
|
|
|
+ List<String> appPermissions = new ArrayList<>();
|
|
|
+ permissionMap.put("app", appPermissions);
|
|
|
+ userPermissions.add("/api/app");
|
|
|
+
|
|
|
+
|
|
|
+ ignoreAuthUrls.add("/api/sso");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 忽略过滤的路径
|
|
|
+ */
|
|
|
+
|
|
|
+// @Value("${com.cuslink.ignoreAuthUrls}")
|
|
|
+// private String ignoreAuthUrls;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
|
|
+ ServerHttpRequest request = exchange.getRequest();
|
|
|
+ ServerHttpResponse response = exchange.getResponse();
|
|
|
+ // 获取当前请求路径
|
|
|
+ String path = request.getURI().getPath();
|
|
|
+ log.info("当前路径为" + path + ",判断是否为忽略路径.");
|
|
|
+ // 查询是否是忽略路径
|
|
|
+ boolean pass = decideIgnore(path);
|
|
|
+ if (pass) {
|
|
|
+ // 忽略路径直接放行
|
|
|
+ log.info("当前路径为" + path + ",是忽略过滤路径,直接放行!");
|
|
|
+ return chain.filter(exchange);
|
|
|
+ } else {
|
|
|
+ ServerCode serverCode = null;
|
|
|
+ log.info("当前路径为" + path + ",不是忽略过滤路径,开始校验!");
|
|
|
+ // 获取当前请求中的token
|
|
|
+ String token = request.getHeaders().getFirst(TOKEN);
|
|
|
+ if(StrUtil.isBlank(token)){
|
|
|
+ serverCode = ServerCode.TOKEN_NOT_FOUND;
|
|
|
+ DataBuffer buffer = setResponseInfo(response, ResultData.error(serverCode.code(), serverCode.message()));
|
|
|
+ return response.writeWith(Mono.just(buffer));
|
|
|
+ }else{
|
|
|
+ //验证token是否被篡改
|
|
|
+ Claims claims = null;
|
|
|
+ try {
|
|
|
+ claims = JwtUtil.parseJWT(token);
|
|
|
+ }catch (Exception e){
|
|
|
+ serverCode = ServerCode.TOKEN_ILLEGAL;
|
|
|
+ DataBuffer buffer = setResponseInfo(response, ResultData.error(serverCode.code(), serverCode.message()));
|
|
|
+ return response.writeWith(Mono.just(buffer));
|
|
|
+ }
|
|
|
+
|
|
|
+ String userName = (String)claims.get("userName");
|
|
|
+ String loginType = (String)claims.get("loginType");
|
|
|
+
|
|
|
+ //查询redis,token是否存在
|
|
|
+ String key = String.format(RedisKey.TOKEN_USER_TYPE, userName, loginType);
|
|
|
+ boolean exist = redisTemplate.hasKey(key);
|
|
|
+ if(!exist){
|
|
|
+ DataBuffer buffer = setResponseInfo(response, ResultData.error(ServerCode.TOKEN_NOT_FOUND.code(), ServerCode.TOKEN_NOT_FOUND.message()));
|
|
|
+ return response.writeWith(Mono.just(buffer));
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: 2021/12/21 校验资源权限 用户资源可以从token中取,这里暂时先写死
|
|
|
+ //根据用户ID查询角色列表
|
|
|
+ //根据角色查询可访问资源权限列表
|
|
|
+ //遍历权限列表,对比path,如果匹配上,则放行
|
|
|
+ List<String> permissions = permissionMap.get(loginType);
|
|
|
+ Boolean isPermission = true;
|
|
|
+ for (String permission : permissions) {
|
|
|
+ if(path.startsWith(permission)){
|
|
|
+ isPermission = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(isPermission){
|
|
|
+ return chain.filter(exchange);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ DataBuffer buffer = setResponseInfo(response, ResultData.error(ServerCode.AUTH_FAIL.code(), ServerCode.AUTH_FAIL.message()));
|
|
|
+ return response.writeWith(Mono.just(buffer));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private DataBuffer setResponseInfo(ServerHttpResponse response, ResultData resultData) {
|
|
|
+ response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
|
|
+ response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
|
|
|
+ byte[] responseByte = JSONUtil.parse(resultData).toString().getBytes();
|
|
|
+ DataBuffer buffer = response.bufferFactory().wrap(responseByte);
|
|
|
+ return buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否是忽略路径
|
|
|
+ *
|
|
|
+ * @param servletPath
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean decideIgnore(String servletPath) {
|
|
|
+ //跳过不需要验证的路径
|
|
|
+ for (String ignore : ignoreAuthUrls) {
|
|
|
+ if (servletPath.startsWith(ignore)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getOrder() {
|
|
|
+ return -101;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|