mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-04-17 07:43:15 +08:00
update 优化 客户端管理 增加白名单路径和白名单IP功能 可限制客户端能访问的具体路径与可访问的具体IP地址
This commit is contained in:
@@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.regex.RegexUtils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -52,7 +53,8 @@ public class NetUtils extends NetUtil {
|
||||
public static boolean isInnerIPv6(String ip) {
|
||||
try {
|
||||
// 判断是否为IPv6地址
|
||||
if (InetAddress.getByName(ip) instanceof Inet6Address inet6Address) {
|
||||
InetAddress inetAddress = InetAddress.getByName(ip);
|
||||
if (inetAddress instanceof Inet6Address inet6Address) {
|
||||
// isAnyLocalAddress 判断是否为通配符地址,通常不会将其视为内网地址,根据业务场景自行处理判断
|
||||
// isLinkLocalAddress 判断是否为链路本地地址,通常不算内网地址,是否划分归属于内网需要根据业务场景自行处理判断
|
||||
// isLoopbackAddress 判断是否为环回地址,与IPv4的 127.0.0.1 同理,用于表示本机
|
||||
@@ -81,4 +83,69 @@ public class NetUtils extends NetUtil {
|
||||
return RegexUtils.isMatch(PatternPool.IPV4, ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配 IP 规则,支持精确值、通配符与 CIDR。
|
||||
*
|
||||
* @param rule IP 规则
|
||||
* @param clientIp 客户端 IP
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public static boolean isMatchIpRule(String rule, String clientIp) {
|
||||
if (StringUtils.isBlank(rule) || StringUtils.isBlank(clientIp)) {
|
||||
return false;
|
||||
}
|
||||
String ipRule = StringUtils.trim(rule);
|
||||
if (StringUtils.equals(ipRule, clientIp)) {
|
||||
return true;
|
||||
}
|
||||
if (ipRule.contains("/")) {
|
||||
return isMatchCidr(ipRule, clientIp);
|
||||
}
|
||||
if (StringUtils.containsAny(ipRule, "*", "?")) {
|
||||
String regex = ipRule
|
||||
.replace(".", "\\.")
|
||||
.replace("*", ".*")
|
||||
.replace("?", ".");
|
||||
return clientIp.matches(regex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配 CIDR 网段。
|
||||
*
|
||||
* @param cidr CIDR 规则
|
||||
* @param clientIp 客户端 IP
|
||||
* @return 是否命中
|
||||
*/
|
||||
public static boolean isMatchCidr(String cidr, String clientIp) {
|
||||
try {
|
||||
String[] parts = cidr.split("/");
|
||||
if (parts.length != 2) {
|
||||
return false;
|
||||
}
|
||||
InetAddress networkAddress = InetAddress.getByName(parts[0]);
|
||||
InetAddress currentAddress = InetAddress.getByName(clientIp);
|
||||
byte[] networkBytes = networkAddress.getAddress();
|
||||
byte[] currentBytes = currentAddress.getAddress();
|
||||
if (networkBytes.length != currentBytes.length) {
|
||||
return false;
|
||||
}
|
||||
int prefixLength = Integer.parseInt(parts[1]);
|
||||
int maxPrefix = networkBytes.length * 8;
|
||||
if (prefixLength < 0 || prefixLength > maxPrefix) {
|
||||
return false;
|
||||
}
|
||||
BigInteger mask = prefixLength == 0
|
||||
? BigInteger.ZERO
|
||||
: BigInteger.ONE.shiftLeft(prefixLength).subtract(BigInteger.ONE).shiftLeft(maxPrefix - prefixLength);
|
||||
BigInteger network = new BigInteger(1, networkBytes);
|
||||
BigInteger current = new BigInteger(1, currentBytes);
|
||||
return network.and(mask).equals(current.and(mask));
|
||||
} catch (UnknownHostException | NumberFormatException e) {
|
||||
log.debug("IP白名单CIDR规则解析失败: {}", cidr, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user