Просмотр исходного кода

gateway 的 GlobalTokenFilter 中添加对访问 url 的 role 检查

reghao 5 месяцев назад
Родитель
Сommit
6ade6095a8

+ 21 - 0
gateway/src/main/java/cn/reghao/tnb/gateway/config/AppProperties.java

@@ -0,0 +1,21 @@
+package cn.reghao.tnb.gateway.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author reghao
+ * @date 2021-12-30 11:01:46
+ */
+@Configuration
+@ConfigurationProperties(prefix = "app")
+@Setter
+@Getter
+public class AppProperties {
+    private Map<String, String> resources;
+}

+ 39 - 3
gateway/src/main/java/cn/reghao/tnb/gateway/token/GlobalTokenFilter.java

@@ -1,7 +1,9 @@
 package cn.reghao.tnb.gateway.token;
 
+import cn.reghao.jutil.jdk.result.WebResult;
 import cn.reghao.jutil.jdk.security.RsaCryptor;
 import cn.reghao.jutil.tool.jwt.Jwt;
+import cn.reghao.tnb.gateway.config.AppProperties;
 import cn.reghao.tnb.gateway.token.model.UserData;
 import cn.reghao.tnb.gateway.token.model.UserLogin;
 import cn.reghao.tnb.gateway.config.RedisKeys;
@@ -18,7 +20,9 @@ import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.http.HttpCookie;
 import org.springframework.http.HttpHeaders;
 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.stereotype.Component;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.server.ServerWebExchange;
@@ -27,8 +31,7 @@ import reactor.core.publisher.Mono;
 
 import java.nio.charset.StandardCharsets;
 import java.security.interfaces.RSAPublicKey;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
@@ -42,9 +45,13 @@ import java.util.stream.Collectors;
 public class GlobalTokenFilter implements GlobalFilter, Ordered {
     private final String cookieName = "USERDATA";
     private final RedisTemplate<String, String> redisTemplate;
+    private final Map<String, String> resourceMap = new HashMap<>();
 
-    public GlobalTokenFilter(RedisTemplate<String, String> redisTemplate) {
+    public GlobalTokenFilter(RedisTemplate<String, String> redisTemplate, AppProperties appProperties) {
         this.redisTemplate = redisTemplate;
+        appProperties.getResources().forEach((key, value) -> {
+            this.resourceMap.put(key.replace("_", "/"), value);
+        });
     }
 
     @Override
@@ -82,6 +89,19 @@ public class GlobalTokenFilter implements GlobalFilter, Ordered {
                 return exchange.getResponse().writeWith(Flux.just(buffer));
             }
         }
+        Set<String> roleSet = Arrays.stream(userLogin.getRoles().split(","))
+                .map(role -> role.toLowerCase(Locale.ROOT))
+                .collect(Collectors.toSet());
+        String url = request.getURI().getPath();
+        for (String urlPrefix : resourceMap.keySet()) {
+            if (url.startsWith(urlPrefix)) {
+                String role = resourceMap.get(urlPrefix);
+                if (!roleSet.contains(role)) {
+                    String errMsg = String.format("access %s require role %s", url, role);
+                    return fastFinish(exchange, errMsg);
+                }
+            }
+        }
 
         final UserLogin userLogin1 = userLogin;
         Consumer<HttpHeaders> headers = header -> {
@@ -142,4 +162,20 @@ public class GlobalTokenFilter implements GlobalFilter, Ordered {
         String pubkey = operations.get(key);
         return pubkey != null ? RsaCryptor.getRSAPublicKey(pubkey) : null;
     }
+
+    /**
+     * 快速返回(不调用业务系统)
+     *
+     * @param
+     * @return
+     * @date 2025-10-17 21:10:660
+     */
+    private Mono<Void> fastFinish(ServerWebExchange exchange, String msg){
+        ServerHttpResponse response = exchange.getResponse();
+        response.setStatusCode(HttpStatus.OK);
+        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+        String fastResult = WebResult.failWithMsg(msg);
+        DataBuffer dataBuffer = response.bufferFactory().allocateBuffer().write(fastResult.getBytes(StandardCharsets.UTF_8));
+        return response.writeWith(Mono.just(dataBuffer));
+    }
 }

+ 7 - 1
gateway/src/main/resources/application.yml

@@ -183,4 +183,10 @@ eureka:
     prefer-ip-address: true
   client:
     register-with-eureka: true
-    fetch-registry: true
+    fetch-registry: true
+app:
+  resources:
+    _api_admin_: role_admin
+    _api_oss_: role_oss
+    _api_content_disk_: role_disk
+    _api_content_exam_: role_exam