diff --git a/web/src/main/java/org/springframework/security/web/util/IpAddressMatcher.java b/web/src/main/java/org/springframework/security/web/util/IpAddressMatcher.java index 91b2223fab..cb966c8451 100644 --- a/web/src/main/java/org/springframework/security/web/util/IpAddressMatcher.java +++ b/web/src/main/java/org/springframework/security/web/util/IpAddressMatcher.java @@ -10,6 +10,9 @@ import org.springframework.util.StringUtils; /** * Matches a request based on IP Address or subnet mask matching against the remote address. + *

+ * Both IPv6 and IPv4 addresses are supported, but a matcher which is configured with an IPv4 address will + * never match a request which returns an IPv6 address, and vice-versa. * * @author Luke Taylor * @since 3.0.2 @@ -40,8 +43,7 @@ public class IpAddressMatcher implements RequestMatcher { InetAddress remoteAddress = parseAddress(request.getRemoteAddr()); if (!requiredAddress.getClass().equals(remoteAddress.getClass())) { - throw new IllegalArgumentException("IP Address in expression must be the same type as " + - "version returned by request"); + return false; } if (nMaskBits == 0) { diff --git a/web/src/test/java/org/springframework/security/web/util/IpAddressMatcherTests.java b/web/src/test/java/org/springframework/security/web/util/IpAddressMatcherTests.java new file mode 100644 index 0000000000..7ae21a0ad6 --- /dev/null +++ b/web/src/test/java/org/springframework/security/web/util/IpAddressMatcherTests.java @@ -0,0 +1,51 @@ +package org.springframework.security.web.util; + + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; + + +/** + * @author Luke Taylor + */ +public class IpAddressMatcherTests { + final IpAddressMatcher v6matcher = new IpAddressMatcher("fe80::21f:5bff:fe33:bd68"); + final IpAddressMatcher v4matcher = new IpAddressMatcher("192.168.1.104"); + MockHttpServletRequest ipv4Request = new MockHttpServletRequest(); + MockHttpServletRequest ipv6Request = new MockHttpServletRequest(); + + @Before + public void setup() { + ipv6Request.setRemoteAddr("fe80::21f:5bff:fe33:bd68"); + ipv4Request.setRemoteAddr("192.168.1.104"); + } + + @Test + public void ipv6MatcherMatchesIpv6Address() { + assertTrue(v6matcher.matches(ipv6Request)); + } + + + @Test + public void ipv6MatcherDoesntMatchIpv4Address() { + assertFalse(v6matcher.matches(ipv4Request)); + } + + @Test + public void ipv4MatcherMatchesIpv4Address() { + assertTrue(v4matcher.matches(ipv4Request)); + } + + @Test + public void ipv4SubnetMatchesCorrectly() throws Exception { + IpAddressMatcher matcher = new IpAddressMatcher("192.168.1.0/24"); + assertTrue(matcher.matches(ipv4Request)); + matcher = new IpAddressMatcher("192.168.1.128/25"); + assertFalse(matcher.matches(ipv4Request)); + ipv4Request.setRemoteAddr("192.168.1.159"); // 159 = 0x9f + assertTrue(matcher.matches(ipv4Request)); + } +}