网关白名单放入nacos配置&支持模糊匹配
This commit is contained in:
		
							parent
							
								
									857a5b26e7
								
							
						
					
					
						commit
						dbadce31c6
					
				| @ -1,6 +1,7 @@ | |||||||
| package com.ruoyi.common.core.utils; | package com.ruoyi.common.core.utils; | ||||||
| 
 | 
 | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import com.ruoyi.common.core.text.StrFormatter; | 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 char SEPARATOR = '_'; | ||||||
| 
 | 
 | ||||||
|  |     /** 星号 */ | ||||||
|  |     private static final String START = "*"; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 获取参数不为空值 |      * 获取参数不为空值 | ||||||
|      *  |      *  | ||||||
| @ -396,6 +400,121 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils | |||||||
|         return sb.toString(); |         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") |     @SuppressWarnings("unchecked") | ||||||
|     public static <T> T cast(Object obj) |     public static <T> T cast(Object obj) | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,9 +1,9 @@ | |||||||
| package com.ruoyi.gateway.filter; | package com.ruoyi.gateway.filter; | ||||||
| 
 | 
 | ||||||
| import java.util.Arrays; |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
| import org.springframework.cloud.gateway.filter.GatewayFilterChain; | import org.springframework.cloud.gateway.filter.GatewayFilterChain; | ||||||
| import org.springframework.cloud.gateway.filter.GlobalFilter; | import org.springframework.cloud.gateway.filter.GlobalFilter; | ||||||
| import org.springframework.core.Ordered; | 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.constant.CacheConstants; | ||||||
| import com.ruoyi.common.core.domain.R; | import com.ruoyi.common.core.domain.R; | ||||||
| import com.ruoyi.common.core.utils.StringUtils; | import com.ruoyi.common.core.utils.StringUtils; | ||||||
|  | import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; | ||||||
| import reactor.core.publisher.Mono; | import reactor.core.publisher.Mono; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -32,9 +33,9 @@ public class AuthFilter implements GlobalFilter, Ordered | |||||||
| { | { | ||||||
|     private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); |     private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); | ||||||
| 
 | 
 | ||||||
|     // 排除过滤的 uri 地址,swagger排除自行添加 |     // 排除过滤的 uri 地址,nacos自行添加 | ||||||
|     private static final String[] whiteList = { "/auth/login", "/code/v2/api-docs", "/schedule/v2/api-docs", |     @Autowired | ||||||
|             "/system/v2/api-docs", "/csrf" }; |     private IgnoreWhiteProperties ignoreWhite; | ||||||
| 
 | 
 | ||||||
|     @Resource(name = "stringRedisTemplate") |     @Resource(name = "stringRedisTemplate") | ||||||
|     private ValueOperations<String, String> sops; |     private ValueOperations<String, String> sops; | ||||||
| @ -44,7 +45,7 @@ public class AuthFilter implements GlobalFilter, Ordered | |||||||
|     { |     { | ||||||
|         String url = exchange.getRequest().getURI().getPath(); |         String url = exchange.getRequest().getURI().getPath(); | ||||||
|         // 跳过不需要验证的路径 |         // 跳过不需要验证的路径 | ||||||
|         if (Arrays.asList(whiteList).contains(url)) |         if (StringUtils.matches(url, ignoreWhite.getWhites())) | ||||||
|         { |         { | ||||||
|             return chain.filter(exchange); |             return chain.filter(exchange); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ CREATE TABLE `config_info` ( | |||||||
| 
 | 
 | ||||||
| insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema) values  | insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema) values  | ||||||
| (1,'application-dev.yml','DEFAULT_GROUP','spring:\n  main:\n    allow-bean-definition-overriding: true\n\n#请求处理的超时时间\nribbon:\n  ReadTimeout: 10000\n  ConnectTimeout: 10000\n\n# feign 配置\nfeign:\n  sentinel:\n    enabled: true\n  okhttp:\n    enabled: true\n  httpclient:\n    enabled: false\n  client:\n    config:\n      default:\n        connectTimeout: 10000\n        readTimeout: 10000\n  compression:\n    request:\n      enabled: true\n    response:\n      enabled: true\n\n# 暴露监控端点\nmanagement:\n  endpoints:\n    web:\n      exposure:\n        include: \'*\'\n','57470c6d167154919418fa150863b7fb','2019-11-29 16:31:20','2020-09-01 09:14:30',NULL,'0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','null'), | (1,'application-dev.yml','DEFAULT_GROUP','spring:\n  main:\n    allow-bean-definition-overriding: true\n\n#请求处理的超时时间\nribbon:\n  ReadTimeout: 10000\n  ConnectTimeout: 10000\n\n# feign 配置\nfeign:\n  sentinel:\n    enabled: true\n  okhttp:\n    enabled: true\n  httpclient:\n    enabled: false\n  client:\n    config:\n      default:\n        connectTimeout: 10000\n        readTimeout: 10000\n  compression:\n    request:\n      enabled: true\n    response:\n      enabled: true\n\n# 暴露监控端点\nmanagement:\n  endpoints:\n    web:\n      exposure:\n        include: \'*\'\n','57470c6d167154919418fa150863b7fb','2019-11-29 16:31:20','2020-09-01 09:14:30',NULL,'0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','null'), | ||||||
| (2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\r\n  redis:\r\n    host: localhost\r\n    port: 6379\r\n    password: \r\n  cloud:\r\n    gateway:\r\n      discovery:\r\n        locator:\r\n          lowerCaseServiceId: true\r\n          enabled: true\r\n      routes:\r\n        # 认证中心\r\n        - id: ruoyi-auth\r\n          uri: lb://ruoyi-auth\r\n          predicates:\r\n            - Path=/auth/**\r\n          filters:\r\n            # 验证码处理\r\n            - CacheRequestFilter\r\n            - ValidateCodeFilter\r\n            - StripPrefix=1\r\n        # 代码生成\r\n        - id: ruoyi-gen\r\n          uri: lb://ruoyi-gen\r\n          predicates:\r\n            - Path=/code/**\r\n          filters:\r\n            - StripPrefix=1\r\n        # 定时任务\r\n        - id: ruoyi-job\r\n          uri: lb://ruoyi-job\r\n          predicates:\r\n            - Path=/schedule/**\r\n          filters:\r\n            - StripPrefix=1\r\n        # 系统模块\r\n        # 系统模块\r\n        - id: ruoyi-system\r\n          uri: lb://ruoyi-system\r\n          predicates:\r\n            - Path=/system/**\r\n          filters:\r\n            - name: BlackListUrlFilter\r\n              args:\r\n                blacklistUrl:\r\n                  - /user/info/*\r\n            - StripPrefix=1\r\n','1c11e0d5e5e4f983f378088740102540','2020-05-14 14:17:55','2020-08-31 20:30:38',NULL,'0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','null'), | (2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\r\n  redis:\r\n    host: localhost\r\n    port: 6379\r\n    password: \r\n  cloud:\r\n    gateway:\r\n      discovery:\r\n        locator:\r\n          lowerCaseServiceId: true\r\n          enabled: true\r\n      routes:\r\n        # 认证中心\r\n        - id: ruoyi-auth\r\n          uri: lb://ruoyi-auth\r\n          predicates:\r\n            - Path=/auth/**\r\n          filters:\r\n            # 验证码处理\r\n            - CacheRequestFilter\r\n            - ValidateCodeFilter\r\n            - StripPrefix=1\r\n        # 代码生成\r\n        - id: ruoyi-gen\r\n          uri: lb://ruoyi-gen\r\n          predicates:\r\n            - Path=/code/**\r\n          filters:\r\n            - StripPrefix=1\r\n        # 定时任务\r\n        - id: ruoyi-job\r\n          uri: lb://ruoyi-job\r\n          predicates:\r\n            - Path=/schedule/**\r\n          filters:\r\n            - StripPrefix=1\r\n        # 系统模块\r\n        - id: ruoyi-system\r\n          uri: lb://ruoyi-system\r\n          predicates:\r\n            - Path=/system/**\r\n          filters:\r\n            - StripPrefix=1\r\n\r\n# 不校验白名单\r\nignore:\r\n  whites:\r\n    - /auth/login\r\n    - /*/v2/api-docs\r\n    - /csrf','842e379b2dfdf0316c020c8dfe2fcb28','2020-05-14 14:17:55','2020-09-13 11:49:19',NULL,'0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','null'), | ||||||
| (3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring: \r\n  datasource:\r\n    driver-class-name: com.mysql.cj.jdbc.Driver\r\n    url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n    username: root\r\n    password: password\r\n  redis:\r\n    host: localhost\r\n    port: 6379\r\n    password: \r\n','868c15010a7a15c027d4c90a48aabb3e','2020-05-14 13:20:49','2020-06-09 16:30:50',NULL,'0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','null'), | (3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring: \r\n  datasource:\r\n    driver-class-name: com.mysql.cj.jdbc.Driver\r\n    url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n    username: root\r\n    password: password\r\n  redis:\r\n    host: localhost\r\n    port: 6379\r\n    password: \r\n','868c15010a7a15c027d4c90a48aabb3e','2020-05-14 13:20:49','2020-06-09 16:30:50',NULL,'0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','null'), | ||||||
| (4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n  security:\r\n    user:\r\n      name: ruoyi\r\n      password: 123456\r\n  boot:\r\n    admin:\r\n      ui:\r\n        title: 若依服务状态监控\r\n','8e49d78998a7780d780305aeefe4fb1b','2020-05-19 15:14:01','2020-05-19 18:50:44',NULL,'0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','null'), | (4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n  security:\r\n    user:\r\n      name: ruoyi\r\n      password: 123456\r\n  boot:\r\n    admin:\r\n      ui:\r\n        title: 若依服务状态监控\r\n','8e49d78998a7780d780305aeefe4fb1b','2020-05-19 15:14:01','2020-05-19 18:50:44',NULL,'0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','null'), | ||||||
| (5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n  redis:\r\n    host: localhost\r\n    port: 6379\r\n    password: \r\n  datasource:\r\n    driver-class-name: com.mysql.cj.jdbc.Driver\r\n    url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n    username: root\r\n    password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n    # 搜索指定包别名\r\n    typeAliasesPackage: com.ruoyi.system\r\n    # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n    mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n  title: 系统模块接口文档\r\n  license: Powered By ruoyi\r\n  licenseUrl: https://ruoyi.vip\r\n  authorization:\r\n    name: RuoYi OAuth\r\n    auth-regex: ^.*$\r\n    authorization-scope-list:\r\n      - scope: server\r\n        description: 客户端授权范围\r\n    token-url-list:\r\n      - http://localhost:8080/auth/oauth/token\r\n','06f95c879d284ec8031cc44805e62b50','2020-05-14 13:37:04','2020-07-02 20:03:46',NULL,'0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','null'), | (5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n  redis:\r\n    host: localhost\r\n    port: 6379\r\n    password: \r\n  datasource:\r\n    driver-class-name: com.mysql.cj.jdbc.Driver\r\n    url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n    username: root\r\n    password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n    # 搜索指定包别名\r\n    typeAliasesPackage: com.ruoyi.system\r\n    # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n    mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n  title: 系统模块接口文档\r\n  license: Powered By ruoyi\r\n  licenseUrl: https://ruoyi.vip\r\n  authorization:\r\n    name: RuoYi OAuth\r\n    auth-regex: ^.*$\r\n    authorization-scope-list:\r\n      - scope: server\r\n        description: 客户端授权范围\r\n    token-url-list:\r\n      - http://localhost:8080/auth/oauth/token\r\n','06f95c879d284ec8031cc44805e62b50','2020-05-14 13:37:04','2020-07-02 20:03:46',NULL,'0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','null'), | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 RuoYi
						RuoYi