浏览代码

Polish IpAddressMatcher

Steve Riesenberg 9 月之前
父节点
当前提交
83a79159b8
共有 1 个文件被更改,包括 33 次插入22 次删除
  1. 33 22
      web/src/main/java/org/springframework/security/web/util/matcher/IpAddressMatcher.java

+ 33 - 22
web/src/main/java/org/springframework/security/web/util/matcher/IpAddressMatcher.java

@@ -18,6 +18,7 @@ package org.springframework.security.web.util.matcher;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.Objects;
 import java.util.regex.Pattern;
 
 import jakarta.servlet.http.HttpServletRequest;
@@ -33,16 +34,17 @@ import org.springframework.util.StringUtils;
  * IPv4 address will never match a request which returns an IPv6 address, and vice-versa.
  *
  * @author Luke Taylor
+ * @author Steve Riesenberg
  * @since 3.0.2
  */
 public final class IpAddressMatcher implements RequestMatcher {
 
 	private static Pattern IPV4 = Pattern.compile("\\d{0,3}.\\d{0,3}.\\d{0,3}.\\d{0,3}(/\\d{0,3})?");
 
-	private final int nMaskBits;
-
 	private final InetAddress requiredAddress;
 
+	private final int nMaskBits;
+
 	/**
 	 * Takes a specific IP address or a range specified using the IP/Netmask (e.g.
 	 * 192.168.1.0/24 or 202.24.0.0/14).
@@ -52,18 +54,22 @@ public final class IpAddressMatcher implements RequestMatcher {
 	public IpAddressMatcher(String ipAddress) {
 		Assert.hasText(ipAddress, "ipAddress cannot be empty");
 		assertNotHostName(ipAddress);
+
+		String requiredAddress;
+		int nMaskBits;
 		if (ipAddress.indexOf('/') > 0) {
-			String[] addressAndMask = StringUtils.split(ipAddress, "/");
-			ipAddress = addressAndMask[0];
-			this.nMaskBits = Integer.parseInt(addressAndMask[1]);
+			String[] parts = Objects.requireNonNull(StringUtils.split(ipAddress, "/"));
+			requiredAddress = parts[0];
+			nMaskBits = Integer.parseInt(parts[1]);
 		}
 		else {
-			this.nMaskBits = -1;
+			requiredAddress = ipAddress;
+			nMaskBits = -1;
 		}
-		this.requiredAddress = parseAddress(ipAddress);
-		String finalIpAddress = ipAddress;
+		this.requiredAddress = parseAddress(requiredAddress);
+		this.nMaskBits = nMaskBits;
 		Assert.isTrue(this.requiredAddress.getAddress().length * 8 >= this.nMaskBits, () -> String
-			.format("IP address %s is too short for bitmask of length %d", finalIpAddress, this.nMaskBits));
+			.format("IP address %s is too short for bitmask of length %d", requiredAddress, this.nMaskBits));
 	}
 
 	@Override
@@ -71,14 +77,14 @@ public final class IpAddressMatcher implements RequestMatcher {
 		return matches(request.getRemoteAddr());
 	}
 
-	public boolean matches(String address) {
+	public boolean matches(String ipAddress) {
 		// Do not match null or blank address
-		if (!StringUtils.hasText(address)) {
+		if (!StringUtils.hasText(ipAddress)) {
 			return false;
 		}
 
-		assertNotHostName(address);
-		InetAddress remoteAddress = parseAddress(address);
+		assertNotHostName(ipAddress);
+		InetAddress remoteAddress = parseAddress(ipAddress);
 		if (!this.requiredAddress.getClass().equals(remoteAddress.getClass())) {
 			return false;
 		}
@@ -88,26 +94,31 @@ public final class IpAddressMatcher implements RequestMatcher {
 		byte[] remAddr = remoteAddress.getAddress();
 		byte[] reqAddr = this.requiredAddress.getAddress();
 		int nMaskFullBytes = this.nMaskBits / 8;
-		byte finalByte = (byte) (0xFF00 >> (this.nMaskBits & 0x07));
 		for (int i = 0; i < nMaskFullBytes; i++) {
 			if (remAddr[i] != reqAddr[i]) {
 				return false;
 			}
 		}
+		byte finalByte = (byte) (0xFF00 >> (this.nMaskBits & 0x07));
 		if (finalByte != 0) {
 			return (remAddr[nMaskFullBytes] & finalByte) == (reqAddr[nMaskFullBytes] & finalByte);
 		}
 		return true;
 	}
 
-	private void assertNotHostName(String ipAddress) {
-		boolean isIpv4 = IPV4.matcher(ipAddress).matches();
-		if (isIpv4) {
-			return;
-		}
-		String error = "ipAddress " + ipAddress + " doesn't look like an IP Address. Is it a host name?";
-		Assert.isTrue(ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
-				|| (Character.digit(ipAddress.charAt(0), 16) != -1 && ipAddress.contains(":")), error);
+	private static void assertNotHostName(String ipAddress) {
+		Assert.isTrue(isIpAddress(ipAddress),
+				() -> String.format("ipAddress %s doesn't look like an IP Address. Is it a host name?", ipAddress));
+	}
+
+	private static boolean isIpAddress(String ipAddress) {
+		// @formatter:off
+		return IPV4.matcher(ipAddress).matches()
+			|| ipAddress.charAt(0) == '['
+			|| ipAddress.charAt(0) == ':'
+			|| Character.digit(ipAddress.charAt(0), 16) != -1
+			&& ipAddress.indexOf(':') > 0;
+		// @formatter:on
 	}
 
 	private InetAddress parseAddress(String address) {