IPV6 vs IPV4 with jetty and hasIpAddress expression
Problem: hasIpAddress throws IllegalArgumentException using Jetty
Using Jetty as the web server and Spring Security 3.0.2.RELEASE throws an "Failed to evaluate expression 'hasIpAddress('127.0.0.1/24')'" exception when trying to
Code:
@PreAuthorize("hasIpAddress('127.0.0.1/24'')")
or
Code:
<secure:http...
access="hasIpAddress('127.0.0.1/24'')"
It fails because requiredAddress is a Inet4Address and the remoteAddress is a Inet6Address throwing the IllegalArgumentException because the two classes are seen as different and incompatible when using the equals function.
Solution
The best way to solve this problem is to simply tell java to use only IPV4 by passing in the parameter:
Code:
-Djava.net.preferIPv4Stack=true
such as
Code:
mvn -Djava.net.preferIPv4Stack=true jetty:run
Root Cause: The problem is in IpAddressMatcher:
Code:
org.springframework.util.StringUtils.IpAddressMatcher
org.springframework.security.web.access.expression.WebSecurityExpressionRoot.hasIpAddress:
public boolean hasIpAddress(String ipAddress) {
return (new IpAddressMatcher(ipAddress).matches(request));
}
org.springframework.util.StringUtils.IpAddressMatc her method called from org.springframework.security.web.access.expression .WebSecurityExpressionRoot.hasIpAddress
on line 44:
Code:
if (!requiredAddress.getClass().equals(remoteAddress.getClass()))
I hope that will save others the day I lost investigating it.
Cheers,