网关IP白名单

获取请求来源IP

方法一:hutool获取
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.5.8</version>
</dependency>

代码

String tagIp = ServletUtil.getClientIP(HttpServletRequest request);
方法二:自定义方法
public String getIpAddr(HttpServletRequest request) {
    final String UNKNOWN = "unknown";
    String ip = request.getHeader("X-Forwarded-For");
    if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_CLIENT_IP");
    }
    if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
    }
    return ip;
} 

注意:第二种获取是通常做法,但是当请求多次转发是,请求头"X-Forwarded-For"会有多个ip地址“,”拼接
下面是改良版的(改版自https://cloud.tencent.com/developer/article/1519081

public class IpUtils {
    public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
    public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");

    public static String longToIpV4(long longIp) {
        int octet3 = (int) ((longIp >> 24) % 256);
        int octet2 = (int) ((longIp >> 16) % 256);
        int octet1 = (int) ((longIp >> 8) % 256);
        int octet0 = (int) ((longIp) % 256);
        return octet3 + "." + octet2 + "." + octet1 + "." + octet0;
    }

    public static long ipV4ToLong(String ip) {
        String[] octets = ip.split("\\.");
        return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16)
                + (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);
    }

    public static boolean isIPv4Private(String ip) {
        long longIp = ipV4ToLong(ip);
        return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255"))
                || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255"))
                || longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255");
    }

    public static boolean isIPv4Valid(String ip) {
        return pattern.matcher(ip).matches();
    }

    public static String validIPAddress(String IP) {
        if (isIPv4(IP)) {
            return "IPv4";
        }
        if (isIPv6(IP)) {
            return "IPv6";
        }
        return "Neither";
    }

    public static boolean isIPv4(String s) {
        return s.matches("^(((([0-9]{1}){1})|(([1-9]{1}[0-9]{1}){1})|((1{1}[0-9]{2}){1})|((2{1}[0-4]{1}[0-9]{1}){1})"
                + "|((2{1}5{1}[0-5]{1}){1})){1}\\.){3}(((([0-9]{1}){1})|(([1-9]{1}[0-9]{1}){1})|((1{1}[0-9]{2}){1})"
                + "|((2{1}[0-4]{1}[0-9]{1}){1})|((2{1}5{1}[0-5]{1}){1})){1})$");
    }

    public static boolean isIPv6(String s) {
        return s.matches("^(((([0-9]|[a-f]|[A-F]){1,4}){1}:{1}){7})((([0-9]|[a-f]|[A-F]){1,4}){1})$");
    }

    public static String getIpFromRequest(HttpServletRequest request) {
        String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
        String ip = null;
        for (String header : headers) {
            boolean found = false;
            ip = request.getHeader(header);
            if (StringUtils.isNotBlank(ip) && "unknown".equalsIgnoreCase(ip)) {
                StrTokenizer tokenizer = new StrTokenizer(ip, ",");
                while (tokenizer.hasNext()) {
                    ip = tokenizer.nextToken().trim();
                    if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                ip = request.getRemoteAddr();
            }
        }
        return ip;
    }
}

ip匹配

全量匹配 127.0.0.1
ipWhiteList.stream().anyMatch("127.0.0.1"::contains)
区间匹配 127.0.0.1-127.0.0.3
ipWhiteList.stream().anyMatch(o -> ipMatch("127.0.0.1", o)
/**
  * ip白名单匹配
  *
  * @param tagIp  目标ip
  * @param ruleIp 规则ip
  * @return 匹配成功1,否0
  */
private boolean ipMatch(String tagIp, String ruleIp) {
    if (ruleIp.contains("-")) {
        String[] split = ruleIp.split("-");
        long start = ip2Long(split[0]);
        long end = ip2Long(split[1]);
        long tag = ip2Long(tagIp);
        return start < tag && tag < end;
    } else {
        return ruleIp.equals(tagIp);
    }
}
/**
  * 将字符串表示的ip地址转换为long表示.
  *
  * @param ip ip地址
  * @return 以32位整数表示的ip地址
  */
 private long ip2Long(final String ip) {
     final String[] ipNums = ip.split("\\.");
     return (Long.parseLong(ipNums[0]) << 24)
             + (Long.parseLong(ipNums[1]) << 16)
             + (Long.parseLong(ipNums[2]) << 8)
             + (Long.parseLong(ipNums[3]));
 }
模糊匹配 127.0.0.*
//替换为正则匹配  ReUtil为hutool工具类
ipWhiteList.stream().anyMatch(o -> ReUtil.contains(o.replace(".", "\\.").replace("*", "\\d{1,3}"),tagIp));

//一分为二 0-255
ipWhiteList.stream().anyMatch(o -> {
    String o2 = o + "";
    long start = ip2Long(o.replace("*", "0"));
    long end = ip2Long(o2.replace("*", "255"));
    long tag = ip2Long(tagIp);
    return start < tag && tag < end;
});
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值