ソースを参照

网关白名单放入nacos配置&支持模糊匹配

RuoYi 5 年 前
コミット
dbadce31c6

+ 119 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java

@@ -1,6 +1,7 @@
 package com.ruoyi.common.core.utils;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import com.ruoyi.common.core.text.StrFormatter;
 
@@ -17,6 +18,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
     /** 下划线 */
     private static final char SEPARATOR = '_';
 
+    /** 星号 */
+    private static final String START = "*";
+
     /**
      * 获取参数不为空值
      * 
@@ -396,6 +400,121 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
         return sb.toString();
     }
 
+    /**
+     * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
+     * 
+     * @param str 指定字符串
+     * @param strs 需要检查的字符串数组
+     * @return 是否匹配
+     */
+    public static boolean matches(String str, List<String> strs)
+    {
+        if (isEmpty(str) || isEmpty(strs))
+        {
+            return false;
+        }
+        for (String testStr : strs)
+        {
+            if (matches(str, testStr))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 查找指定字符串是否匹配指定字符串数组中的任意一个字符串
+     * 
+     * @param str 指定字符串
+     * @param strs 需要检查的字符串数组
+     * @return 是否匹配
+     */
+    public static boolean matches(String str, String... strs)
+    {
+        if (isEmpty(str) || isEmpty(strs))
+        {
+            return false;
+        }
+        for (String testStr : strs)
+        {
+            if (matches(str, testStr))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 查找指定字符串是否匹配
+     * 
+     * @param str 指定字符串
+     * @param pattern 需要检查的字符串
+     * @return 是否匹配
+     */
+    public static boolean matches(String str, String pattern)
+    {
+        if (isEmpty(pattern) || isEmpty(str))
+        {
+            return false;
+        }
+
+        pattern = pattern.replaceAll("\\s*", ""); // 替换空格
+        int beginOffset = 0; // pattern截取开始位置
+        int formerStarOffset = -1; // 前星号的偏移位置
+        int latterStarOffset = -1; // 后星号的偏移位置
+
+        String remainingURI = str;
+        String prefixPattern = "";
+        String suffixPattern = "";
+
+        boolean result = false;
+        do
+        {
+            formerStarOffset = indexOf(pattern, START, beginOffset);
+            prefixPattern = substring(pattern, beginOffset, formerStarOffset > -1 ? formerStarOffset : pattern.length());
+
+            // 匹配前缀Pattern
+            result = remainingURI.contains(prefixPattern);
+            // 已经没有星号,直接返回
+            if (formerStarOffset == -1)
+            {
+                return result;
+            }
+
+            // 匹配失败,直接返回
+            if (!result)
+                return false;
+
+            if (!isEmpty(prefixPattern))
+            {
+                remainingURI = substringAfter(str, prefixPattern);
+            }
+
+            // 匹配后缀Pattern
+            latterStarOffset = indexOf(pattern, START, formerStarOffset + 1);
+            suffixPattern = substring(pattern, formerStarOffset + 1, latterStarOffset > -1 ? latterStarOffset : pattern.length());
+
+            result = remainingURI.contains(suffixPattern);
+            // 匹配失败,直接返回
+            if (!result)
+                return false;
+
+            if (!isEmpty(suffixPattern))
+            {
+                remainingURI = substringAfter(str, suffixPattern);
+            }
+
+            // 移动指针
+            beginOffset = latterStarOffset + 1;
+
+        }
+        while (!isEmpty(suffixPattern) && !isEmpty(remainingURI));
+
+        return true;
+    }
+
     @SuppressWarnings("unchecked")
     public static <T> T cast(Object obj)
     {

+ 33 - 0
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java

@@ -0,0 +1,33 @@
+package com.ruoyi.gateway.config.properties;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 放行白名单配置
+ * 
+ * @author ruoyi
+ */
+@Configuration
+@RefreshScope
+@ConfigurationProperties(prefix = "ignore")
+public class IgnoreWhiteProperties
+{
+    /**
+     * 放行白名单配置,网关不校验此处的白名单
+     */
+    private List<String> whites = new ArrayList<>();
+
+    public List<String> getWhites()
+    {
+        return whites;
+    }
+
+    public void setWhites(List<String> whites)
+    {
+        this.whites = whites;
+    }
+}

+ 7 - 6
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java

@@ -1,9 +1,9 @@
 package com.ruoyi.gateway.filter;
 
-import java.util.Arrays;
 import javax.annotation.Resource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+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;
@@ -20,6 +20,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.common.core.constant.CacheConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties;
 import reactor.core.publisher.Mono;
 
 /**
@@ -32,9 +33,9 @@ public class AuthFilter implements GlobalFilter, Ordered
 {
     private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
 
-    // 排除过滤的 uri 地址,swagger排除自行添加
-    private static final String[] whiteList = { "/auth/login", "/code/v2/api-docs", "/schedule/v2/api-docs",
-            "/system/v2/api-docs", "/csrf" };
+    // 排除过滤的 uri 地址,nacos自行添加
+    @Autowired
+    private IgnoreWhiteProperties ignoreWhite;
 
     @Resource(name = "stringRedisTemplate")
     private ValueOperations<String, String> sops;
@@ -44,7 +45,7 @@ public class AuthFilter implements GlobalFilter, Ordered
     {
         String url = exchange.getRequest().getURI().getPath();
         // 跳过不需要验证的路径
-        if (Arrays.asList(whiteList).contains(url))
+        if (StringUtils.matches(url, ignoreWhite.getWhites()))
         {
             return chain.filter(exchange);
         }
@@ -69,7 +70,7 @@ public class AuthFilter implements GlobalFilter, Ordered
         ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(CacheConstants.DETAILS_USER_ID, userid)
                 .header(CacheConstants.DETAILS_USERNAME, username).build();
         ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
-        
+
         return chain.filter(mutableExchange);
     }
 

ファイルの差分が大きいため隠しています
+ 1 - 1
sql/ry_config_20200901.sql