You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
11 KiB
374 lines
11 KiB
2 years ago
|
package com.fr.plugin.cpic.utils;
|
||
|
|
||
|
/**
|
||
|
* IP校验类的方法
|
||
|
*/
|
||
|
|
||
|
import com.fanruan.api.util.StringKit;
|
||
|
import com.fr.plugin.cpic.config.CpicCustomConfig;
|
||
|
|
||
|
import javax.servlet.http.HttpServletRequest;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.HashSet;
|
||
|
import java.util.List;
|
||
|
import java.util.Set;
|
||
|
import java.util.regex.Pattern;
|
||
|
|
||
|
|
||
|
public class IPWhiteListUtil {
|
||
|
|
||
|
private static final String[] PROXYS = {"x-forwarded-for", "Proxy-Client-IP", "WL-Proxy-Client-IP", "X-Real-IP", "HTTP_CLIENT_IP"};
|
||
|
|
||
|
// IP的正则
|
||
|
private static Pattern pattern = Pattern
|
||
|
.compile("(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
|
||
|
+ "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
|
||
|
+ "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})\\."
|
||
|
+ "(1\\d{1,2}|2[0-4]\\d|25[0-5]|\\d{1,2})");
|
||
|
|
||
|
/**
|
||
|
* getAvaliIpList:(根据IP白名单设置获取可用的IP列表).
|
||
|
*
|
||
|
* @return
|
||
|
*/
|
||
|
private static Set getAvaliIpList(String allowIp) {
|
||
|
Set<String> ipList = new HashSet();
|
||
|
for (String allow : allowIp.replaceAll("\\s", "").split(";")) {
|
||
|
if (allow.indexOf("*") > -1) {
|
||
|
String[] ips = allow.split("\\.");
|
||
|
String[] from = new String[]{"0", "0", "0", "0"};
|
||
|
String[] end = new String[]{"255", "255", "255", "255"};
|
||
|
List<String> tem = new ArrayList();
|
||
|
for (int i = 0; i < ips.length; i++)
|
||
|
if (ips[i].indexOf("*") > -1) {
|
||
|
tem = complete(ips[i]);
|
||
|
from[i] = null;
|
||
|
end[i] = null;
|
||
|
} else {
|
||
|
from[i] = ips[i];
|
||
|
end[i] = ips[i];
|
||
|
}
|
||
|
StringBuffer fromIP = new StringBuffer();
|
||
|
StringBuffer endIP = new StringBuffer();
|
||
|
for (int i = 0; i < 4; i++) {
|
||
|
if (from[i] != null) {
|
||
|
fromIP.append(from[i]).append(".");
|
||
|
endIP.append(end[i]).append(".");
|
||
|
} else {
|
||
|
fromIP.append("[*].");
|
||
|
endIP.append("[*].");
|
||
|
}
|
||
|
}
|
||
|
fromIP.deleteCharAt(fromIP.length() - 1);
|
||
|
endIP.deleteCharAt(endIP.length() - 1);
|
||
|
for (String s : tem) {
|
||
|
String ip = fromIP.toString().replace("[*]",
|
||
|
s.split(";")[0])
|
||
|
+ "-"
|
||
|
+ endIP.toString().replace("[*]", s.split(";")[1]);
|
||
|
|
||
|
if (validate(ip)) {
|
||
|
ipList.add(ip);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
if (validate(allow)) {
|
||
|
ipList.add(allow);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ipList;
|
||
|
}
|
||
|
|
||
|
private static Set getAvaliIpList(Set<String> ipSet) {
|
||
|
Set<String> ipList = new HashSet();
|
||
|
for (String allow : ipSet) {
|
||
|
if (allow.indexOf("*") > -1) {
|
||
|
String[] ips = allow.split("\\.");
|
||
|
String[] from = new String[]{"0", "0", "0", "0"};
|
||
|
String[] end = new String[]{"255", "255", "255", "255"};
|
||
|
List<String> tem = new ArrayList();
|
||
|
for (int i = 0; i < ips.length; i++)
|
||
|
if (ips[i].indexOf("*") > -1) {
|
||
|
tem = complete(ips[i]);
|
||
|
from[i] = null;
|
||
|
end[i] = null;
|
||
|
} else {
|
||
|
from[i] = ips[i];
|
||
|
end[i] = ips[i];
|
||
|
}
|
||
|
StringBuffer fromIP = new StringBuffer();
|
||
|
StringBuffer endIP = new StringBuffer();
|
||
|
for (int i = 0; i < 4; i++) {
|
||
|
if (from[i] != null) {
|
||
|
fromIP.append(from[i]).append(".");
|
||
|
endIP.append(end[i]).append(".");
|
||
|
} else {
|
||
|
fromIP.append("[*].");
|
||
|
endIP.append("[*].");
|
||
|
}
|
||
|
}
|
||
|
fromIP.deleteCharAt(fromIP.length() - 1);
|
||
|
|
||
|
endIP.deleteCharAt(endIP.length() - 1);
|
||
|
|
||
|
|
||
|
for (String s : tem) {
|
||
|
String ip = fromIP.toString().replace("[*]",
|
||
|
s.split(";")[0])
|
||
|
+ "-"
|
||
|
+ endIP.toString().replace("[*]", s.split(";")[1]);
|
||
|
if (validate(ip)) {
|
||
|
ipList.add(ip);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if (validate(allow)) {
|
||
|
ipList.add(allow);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ipList;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 对单个IP节点进行范围限定
|
||
|
*
|
||
|
* @param arg
|
||
|
* @return 返回限定后的IP范围,格式为List[10;19, 100;199]
|
||
|
*/
|
||
|
|
||
|
private static List complete(String arg) {
|
||
|
List com = new ArrayList();
|
||
|
if (arg.length() == 1) {
|
||
|
com.add("0;255");
|
||
|
} else if (arg.length() == 2) {
|
||
|
String s1 = complete(arg, 1);
|
||
|
if (s1 != null) {
|
||
|
com.add(s1);
|
||
|
}
|
||
|
String s2 = complete(arg, 2);
|
||
|
if (s2 != null) {
|
||
|
com.add(s2);
|
||
|
}
|
||
|
} else {
|
||
|
String s1 = complete(arg, 1);
|
||
|
if (s1 != null) {
|
||
|
com.add(s1);
|
||
|
}
|
||
|
}
|
||
|
return com;
|
||
|
}
|
||
|
|
||
|
private static String complete(String arg, int length) {
|
||
|
|
||
|
String from = "";
|
||
|
|
||
|
String end = "";
|
||
|
|
||
|
if (length == 1) {
|
||
|
|
||
|
from = arg.replace("*", "0");
|
||
|
|
||
|
end = arg.replace("*", "9");
|
||
|
|
||
|
} else {
|
||
|
|
||
|
from = arg.replace("*", "00");
|
||
|
|
||
|
end = arg.replace("*", "99");
|
||
|
|
||
|
}
|
||
|
|
||
|
if (Integer.valueOf(from) > 255) {
|
||
|
return null;
|
||
|
}
|
||
|
if (Integer.valueOf(end) > 255) {
|
||
|
end = "255";
|
||
|
}
|
||
|
return from + ";" + end;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* 在添加至白名单时进行格式校验
|
||
|
*
|
||
|
* @param ip
|
||
|
* @return
|
||
|
*/
|
||
|
|
||
|
private static boolean validate(String ip) {
|
||
|
|
||
|
for (String s : ip.split("-")) {
|
||
|
if (!pattern.matcher(s).matches()) {
|
||
|
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* checkLoginIP:(根据IP,及可用Ip列表来判断ip是否包含在白名单之中).
|
||
|
*
|
||
|
* @param ip
|
||
|
* @param ipList
|
||
|
* @return
|
||
|
*/
|
||
|
|
||
|
private static boolean checkLoginIP(String ip, Set<String> ipList) {
|
||
|
if (ipList.contains(ip)) {
|
||
|
return true;
|
||
|
} else {
|
||
|
for (String allow : ipList) {
|
||
|
if (allow.indexOf("-") > -1) {
|
||
|
String[] from = allow.split("-")[0].split("\\.");
|
||
|
String[] end = allow.split("-")[1].split("\\.");
|
||
|
String[] tag = ip.split("\\.");
|
||
|
// 对IP从左到右进行逐段匹配
|
||
|
boolean check = true;
|
||
|
for (int i = 0; i < 4; i++) {
|
||
|
int s = Integer.valueOf(from[i]);
|
||
|
int t = Integer.valueOf(tag[i]);
|
||
|
int e = Integer.valueOf(end[i]);
|
||
|
if (!(s <= t && t <= e)) {
|
||
|
check = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (check) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* checkLoginIP:(根据IP地址,及IP白名单设置规则判断IP是否包含在白名单).
|
||
|
*
|
||
|
* @param request
|
||
|
* @return
|
||
|
*/
|
||
|
|
||
|
public static boolean checkIpIsWhite(HttpServletRequest request) {
|
||
|
// 获取配置
|
||
|
CpicCustomConfig config = CpicCustomConfig.getInstance();
|
||
|
String ipWhiteValue = config.getIpWhiteValue();
|
||
|
if (StringKit.isBlank(ipWhiteValue)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// 获取当前请求IP
|
||
|
String ip = IPWhiteListUtil.getIpAddr(request);
|
||
|
|
||
|
// 获取白名单全部IP
|
||
|
Set ipList = getAvaliIpList(ipWhiteValue);
|
||
|
|
||
|
// 返回结果
|
||
|
return checkLoginIP(ip, ipList);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* ip在ipList中,则返回true
|
||
|
*
|
||
|
* @param ip
|
||
|
* @param ipList
|
||
|
* @return
|
||
|
*/
|
||
|
|
||
|
public static boolean checkIpList(String ip, List<String> ipList) {
|
||
|
|
||
|
Set<String> ipSet = new HashSet();
|
||
|
|
||
|
for (String ipStr : ipList) {
|
||
|
|
||
|
if (!ipStr.trim().startsWith("#")) {
|
||
|
|
||
|
ipSet.add(ipStr.trim());
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ipSet = getAvaliIpList(ipSet);
|
||
|
|
||
|
return checkLoginIP(ip, ipSet);
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取请求中的IP地址
|
||
|
*
|
||
|
* @param request
|
||
|
* @return
|
||
|
*/
|
||
|
public static String getIpAddr(HttpServletRequest request) {
|
||
|
String ipAddress = null;
|
||
|
|
||
|
try {
|
||
|
for (String proxy : PROXYS) {
|
||
|
ipAddress = request.getHeader(proxy);
|
||
|
if (StringKit.isNotBlank(ipAddress) && !"unknown".equalsIgnoreCase(ipAddress)) {
|
||
|
return ipAddress;
|
||
|
}
|
||
|
}
|
||
|
if (StringKit.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
|
||
|
ipAddress = request.getRemoteAddr();
|
||
|
// if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
|
||
|
// // 根据网卡取本机配置的IP
|
||
|
// InetAddress inet = null;
|
||
|
// try {
|
||
|
// inet = InetAddress.getLocalHost();
|
||
|
// } catch (UnknownHostException e) {
|
||
|
// e.printStackTrace();
|
||
|
// }
|
||
|
// ipAddress = inet.getHostAddress();
|
||
|
// }
|
||
|
}
|
||
|
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
|
||
|
// "***.***.***.***".length() = 15
|
||
|
if (ipAddress != null && ipAddress.length() > 15) {
|
||
|
if (ipAddress.indexOf(",") > 0) {
|
||
|
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
|
||
|
}
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
ipAddress = "";
|
||
|
}
|
||
|
return ipAddress;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 测试
|
||
|
|
||
|
public static void main(String[] args) {
|
||
|
|
||
|
List<String> ipWhilte = new ArrayList<>();
|
||
|
ipWhilte.add("192.168.1.1"); //设置单个IP的白名单
|
||
|
ipWhilte.add("192.168.2.*"); //设置ip通配符,对一个ip段进行匹配
|
||
|
ipWhilte.add("192.168.3.17-192.168.3.38"); //设置一个IP范围
|
||
|
|
||
|
System.out.println(ipWhilte);
|
||
|
boolean flag = checkIpList("192.168.2.2", ipWhilte);
|
||
|
boolean flag2 = checkIpList("192.168.1.2", ipWhilte);
|
||
|
boolean flag3 = checkIpList("192.168.3.16", ipWhilte);
|
||
|
boolean flag4 = checkIpList("192.168.3.17", ipWhilte);
|
||
|
System.out.println(flag); //true
|
||
|
System.out.println(flag2); //false
|
||
|
System.out.println(flag3); //false
|
||
|
System.out.println(flag4); //true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|