|
|
|
|
@ -2,6 +2,7 @@ package org.springframework.security.expression.support;
@@ -2,6 +2,7 @@ package org.springframework.security.expression.support;
|
|
|
|
|
|
|
|
|
|
import java.net.InetAddress; |
|
|
|
|
import java.net.UnknownHostException; |
|
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
|
|
import org.springframework.security.Authentication; |
|
|
|
|
import org.springframework.security.intercept.web.FilterInvocation; |
|
|
|
|
@ -21,33 +22,64 @@ class WebSecurityExpressionRoot extends SecurityExpressionRoot {
@@ -21,33 +22,64 @@ class WebSecurityExpressionRoot extends SecurityExpressionRoot {
|
|
|
|
|
this.filterInvocation = fi; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Takes a specific IP address or a range using the IP/Netmask (e.g. 192.168.1.0/24 or 202.24.0.0/14). |
|
|
|
|
* |
|
|
|
|
* @param ipAddress the address or range of addresses from which the request must come. |
|
|
|
|
* @return true if the IP address of the current request is in the required range. |
|
|
|
|
*/ |
|
|
|
|
public boolean hasIpAddress(String ipAddress) { |
|
|
|
|
byte[] mask = null; |
|
|
|
|
int nMaskBits = 0; |
|
|
|
|
|
|
|
|
|
if (ipAddress.indexOf('/') > 0) { |
|
|
|
|
String[] addressAndMask = StringUtils.split(ipAddress, "/"); |
|
|
|
|
ipAddress = addressAndMask[0]; |
|
|
|
|
try { |
|
|
|
|
mask = InetAddress.getByName(addressAndMask[1]).getAddress(); |
|
|
|
|
} catch (UnknownHostException e) { |
|
|
|
|
throw new IllegalArgumentException("Failed to parse mask" + addressAndMask[1], e); |
|
|
|
|
} |
|
|
|
|
nMaskBits = Integer.parseInt(addressAndMask[1]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
InetAddress requiredAddress = InetAddress.getByName(ipAddress); |
|
|
|
|
InetAddress remoteAddress = InetAddress.getByName(filterInvocation.getHttpRequest().getRemoteAddr()); |
|
|
|
|
InetAddress requiredAddress = parseAddress(ipAddress); |
|
|
|
|
InetAddress remoteAddress = parseAddress(filterInvocation.getHttpRequest().getRemoteAddr()); |
|
|
|
|
|
|
|
|
|
if (mask == null) { |
|
|
|
|
return remoteAddress.equals(requiredAddress); |
|
|
|
|
} else { |
|
|
|
|
if (!requiredAddress.getClass().equals(remoteAddress.getClass())) { |
|
|
|
|
throw new IllegalArgumentException("IP Address in expression must be the same type as " + |
|
|
|
|
"version returned by request"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (nMaskBits == 0) { |
|
|
|
|
return remoteAddress.equals(requiredAddress); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
byte[] remAddr = remoteAddress.getAddress(); |
|
|
|
|
byte[] reqAddr = requiredAddress.getAddress(); |
|
|
|
|
|
|
|
|
|
int oddBits = nMaskBits % 8; |
|
|
|
|
int nMaskBytes = nMaskBits/8 + (oddBits == 0 ? 0 : 1); |
|
|
|
|
byte[] mask = new byte[nMaskBytes]; |
|
|
|
|
|
|
|
|
|
Arrays.fill(mask, 0, oddBits == 0 ? mask.length : mask.length - 1, (byte)0xFF); |
|
|
|
|
|
|
|
|
|
if (oddBits != 0) { |
|
|
|
|
int finalByte = (1 << oddBits) - 1; |
|
|
|
|
finalByte <<= 8-oddBits; |
|
|
|
|
mask[mask.length - 1] = (byte) finalByte; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// System.out.println("Mask is " + new sun.misc.HexDumpEncoder().encode(mask));
|
|
|
|
|
|
|
|
|
|
for (int i=0; i < mask.length; i++) { |
|
|
|
|
if ((remAddr[i] & mask[i]) != (reqAddr[i] & mask[i])) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
// byte[] remoteAddress = InetAddress.getByName(filterInvocation.getHttpRequest().getRemoteAddr()).getAddress();
|
|
|
|
|
} catch (UnknownHostException e) { |
|
|
|
|
throw new IllegalArgumentException("Failed to parse " + ipAddress, e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private InetAddress parseAddress(String address) { |
|
|
|
|
try { |
|
|
|
|
return InetAddress.getByName(address); |
|
|
|
|
} catch (UnknownHostException e) { |
|
|
|
|
throw new IllegalArgumentException("Failed to parse address" + address, e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|