IpUtils.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. package com.ruoyi.common.utils.ip;
  2. import java.net.InetAddress;
  3. import java.net.UnknownHostException;
  4. import javax.servlet.http.HttpServletRequest;
  5. import com.ruoyi.common.utils.ServletUtils;
  6. import com.ruoyi.common.utils.StringUtils;
  7. /**
  8. * 获取IP方法
  9. *
  10. * @author ruoyi
  11. */
  12. public class IpUtils
  13. {
  14. public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
  15. // 匹配 ip
  16. public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
  17. public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
  18. // 匹配网段
  19. public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
  20. /**
  21. * 获取客户端IP
  22. *
  23. * @return IP地址
  24. */
  25. public static String getIpAddr()
  26. {
  27. return getIpAddr(ServletUtils.getRequest());
  28. }
  29. /**
  30. * 获取客户端IP
  31. *
  32. * @param request 请求对象
  33. * @return IP地址
  34. */
  35. public static String getIpAddr(HttpServletRequest request)
  36. {
  37. if (request == null)
  38. {
  39. return "unknown";
  40. }
  41. String ip = request.getHeader("x-forwarded-for");
  42. if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
  43. {
  44. ip = request.getHeader("Proxy-Client-IP");
  45. }
  46. if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
  47. {
  48. ip = request.getHeader("X-Forwarded-For");
  49. }
  50. if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
  51. {
  52. ip = request.getHeader("WL-Proxy-Client-IP");
  53. }
  54. if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
  55. {
  56. ip = request.getHeader("X-Real-IP");
  57. }
  58. if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
  59. {
  60. ip = request.getRemoteAddr();
  61. }
  62. return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
  63. }
  64. /**
  65. * 检查是否为内部IP地址
  66. *
  67. * @param ip IP地址
  68. * @return 结果
  69. */
  70. public static boolean internalIp(String ip)
  71. {
  72. byte[] addr = textToNumericFormatV4(ip);
  73. return internalIp(addr) || "127.0.0.1".equals(ip);
  74. }
  75. /**
  76. * 检查是否为内部IP地址
  77. *
  78. * @param addr byte地址
  79. * @return 结果
  80. */
  81. private static boolean internalIp(byte[] addr)
  82. {
  83. if (StringUtils.isNull(addr) || addr.length < 2)
  84. {
  85. return true;
  86. }
  87. final byte b0 = addr[0];
  88. final byte b1 = addr[1];
  89. // 10.x.x.x/8
  90. final byte SECTION_1 = 0x0A;
  91. // 172.16.x.x/12
  92. final byte SECTION_2 = (byte) 0xAC;
  93. final byte SECTION_3 = (byte) 0x10;
  94. final byte SECTION_4 = (byte) 0x1F;
  95. // 192.168.x.x/16
  96. final byte SECTION_5 = (byte) 0xC0;
  97. final byte SECTION_6 = (byte) 0xA8;
  98. switch (b0)
  99. {
  100. case SECTION_1:
  101. return true;
  102. case SECTION_2:
  103. if (b1 >= SECTION_3 && b1 <= SECTION_4)
  104. {
  105. return true;
  106. }
  107. case SECTION_5:
  108. switch (b1)
  109. {
  110. case SECTION_6:
  111. return true;
  112. }
  113. default:
  114. return false;
  115. }
  116. }
  117. /**
  118. * 将IPv4地址转换成字节
  119. *
  120. * @param text IPv4地址
  121. * @return byte 字节
  122. */
  123. public static byte[] textToNumericFormatV4(String text)
  124. {
  125. if (text.length() == 0)
  126. {
  127. return null;
  128. }
  129. byte[] bytes = new byte[4];
  130. String[] elements = text.split("\\.", -1);
  131. try
  132. {
  133. long l;
  134. int i;
  135. switch (elements.length)
  136. {
  137. case 1:
  138. l = Long.parseLong(elements[0]);
  139. if ((l < 0L) || (l > 4294967295L))
  140. {
  141. return null;
  142. }
  143. bytes[0] = (byte) (int) (l >> 24 & 0xFF);
  144. bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
  145. bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
  146. bytes[3] = (byte) (int) (l & 0xFF);
  147. break;
  148. case 2:
  149. l = Integer.parseInt(elements[0]);
  150. if ((l < 0L) || (l > 255L))
  151. {
  152. return null;
  153. }
  154. bytes[0] = (byte) (int) (l & 0xFF);
  155. l = Integer.parseInt(elements[1]);
  156. if ((l < 0L) || (l > 16777215L))
  157. {
  158. return null;
  159. }
  160. bytes[1] = (byte) (int) (l >> 16 & 0xFF);
  161. bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
  162. bytes[3] = (byte) (int) (l & 0xFF);
  163. break;
  164. case 3:
  165. for (i = 0; i < 2; ++i)
  166. {
  167. l = Integer.parseInt(elements[i]);
  168. if ((l < 0L) || (l > 255L))
  169. {
  170. return null;
  171. }
  172. bytes[i] = (byte) (int) (l & 0xFF);
  173. }
  174. l = Integer.parseInt(elements[2]);
  175. if ((l < 0L) || (l > 65535L))
  176. {
  177. return null;
  178. }
  179. bytes[2] = (byte) (int) (l >> 8 & 0xFF);
  180. bytes[3] = (byte) (int) (l & 0xFF);
  181. break;
  182. case 4:
  183. for (i = 0; i < 4; ++i)
  184. {
  185. l = Integer.parseInt(elements[i]);
  186. if ((l < 0L) || (l > 255L))
  187. {
  188. return null;
  189. }
  190. bytes[i] = (byte) (int) (l & 0xFF);
  191. }
  192. break;
  193. default:
  194. return null;
  195. }
  196. }
  197. catch (NumberFormatException e)
  198. {
  199. return null;
  200. }
  201. return bytes;
  202. }
  203. /**
  204. * 获取IP地址
  205. *
  206. * @return 本地IP地址
  207. */
  208. public static String getHostIp()
  209. {
  210. try
  211. {
  212. return InetAddress.getLocalHost().getHostAddress();
  213. }
  214. catch (UnknownHostException e)
  215. {
  216. }
  217. return "127.0.0.1";
  218. }
  219. /**
  220. * 获取主机名
  221. *
  222. * @return 本地主机名
  223. */
  224. public static String getHostName()
  225. {
  226. try
  227. {
  228. return InetAddress.getLocalHost().getHostName();
  229. }
  230. catch (UnknownHostException e)
  231. {
  232. }
  233. return "未知";
  234. }
  235. /**
  236. * 从多级反向代理中获得第一个非unknown IP地址
  237. *
  238. * @param ip 获得的IP地址
  239. * @return 第一个非unknown IP地址
  240. */
  241. public static String getMultistageReverseProxyIp(String ip)
  242. {
  243. // 多级反向代理检测
  244. if (ip != null && ip.indexOf(",") > 0)
  245. {
  246. final String[] ips = ip.trim().split(",");
  247. for (String subIp : ips)
  248. {
  249. if (false == isUnknown(subIp))
  250. {
  251. ip = subIp;
  252. break;
  253. }
  254. }
  255. }
  256. return StringUtils.substring(ip, 0, 255);
  257. }
  258. /**
  259. * 检测给定字符串是否为未知,多用于检测HTTP请求相关
  260. *
  261. * @param checkString 被检测的字符串
  262. * @return 是否未知
  263. */
  264. public static boolean isUnknown(String checkString)
  265. {
  266. return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
  267. }
  268. /**
  269. * 是否为IP
  270. */
  271. public static boolean isIP(String ip)
  272. {
  273. return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
  274. }
  275. /**
  276. * 是否为IP,或 *为间隔的通配符地址
  277. */
  278. public static boolean isIpWildCard(String ip)
  279. {
  280. return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
  281. }
  282. /**
  283. * 检测参数是否在ip通配符里
  284. */
  285. public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
  286. {
  287. String[] s1 = ipWildCard.split("\\.");
  288. String[] s2 = ip.split("\\.");
  289. boolean isMatchedSeg = true;
  290. for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
  291. {
  292. if (!s1[i].equals(s2[i]))
  293. {
  294. isMatchedSeg = false;
  295. break;
  296. }
  297. }
  298. return isMatchedSeg;
  299. }
  300. /**
  301. * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
  302. */
  303. public static boolean isIPSegment(String ipSeg)
  304. {
  305. return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
  306. }
  307. /**
  308. * 判断ip是否在指定网段中
  309. */
  310. public static boolean ipIsInNetNoCheck(String iparea, String ip)
  311. {
  312. int idx = iparea.indexOf('-');
  313. String[] sips = iparea.substring(0, idx).split("\\.");
  314. String[] sipe = iparea.substring(idx + 1).split("\\.");
  315. String[] sipt = ip.split("\\.");
  316. long ips = 0L, ipe = 0L, ipt = 0L;
  317. for (int i = 0; i < 4; ++i)
  318. {
  319. ips = ips << 8 | Integer.parseInt(sips[i]);
  320. ipe = ipe << 8 | Integer.parseInt(sipe[i]);
  321. ipt = ipt << 8 | Integer.parseInt(sipt[i]);
  322. }
  323. if (ips > ipe)
  324. {
  325. long t = ips;
  326. ips = ipe;
  327. ipe = t;
  328. }
  329. return ips <= ipt && ipt <= ipe;
  330. }
  331. /**
  332. * 校验ip是否符合过滤串规则
  333. *
  334. * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
  335. * @param ip 校验IP地址
  336. * @return boolean 结果
  337. */
  338. public static boolean isMatchedIp(String filter, String ip)
  339. {
  340. if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
  341. {
  342. return false;
  343. }
  344. String[] ips = filter.split(";");
  345. for (String iStr : ips)
  346. {
  347. if (isIP(iStr) && iStr.equals(ip))
  348. {
  349. return true;
  350. }
  351. else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
  352. {
  353. return true;
  354. }
  355. else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
  356. {
  357. return true;
  358. }
  359. }
  360. return false;
  361. }
  362. }