JSP中的IP子网验证

时间:2008-10-07 12:25:32

标签: java ip-address netmask

我有以下JSP代码,它保护我的网页并仅显示知道IP的

String ip_h = request.getRemoteAddr();  
String host_h = request.getRemoteHost();  
String iplist[] = new String[1];  
iplist[0] = "127.0.0.1";  
iplist[1] = "10.217.106.248";  

int count = iplist.length;  
boolean flag = false;  
int zz = 0;  
//return;
System.out.println(host_h);  
while ( (flag==false) && ( zz < count) )  
{  
   if (ip_h.equals(iplist[zz]) || host_h.equals(iplist[zz]) )  
   {  
      flag = true;  
   }  
   zz++;  
}

但是,我宁愿检查子网范围,即允许属于10.217.0.0/16的所有用户。

我该怎么做?

5 个答案:

答案 0 :(得分:2)

IP地址(至少是IPv4地址)实际上是要表示为32位整数。如果首先将IP地址转换为整数,则检查子网范围变得相对简单(在您的示例中)检查前16位是否与范围的前16位匹配。

答案 1 :(得分:2)

你不宁愿使用应用程序服务器来锁定ip范围吗?在apache中,您可以为目录创建别名,将代码放在目录中,然后在alias指令中只允许某些ip或范围:

Alias / mydir“/ usr / local / mydir”

    命令拒绝,允许     否认所有人     允许来自10.217.106.248     允许来自127.0.0.1     允许来自10.217.106#这是一个范围

这样你就不必编码这种“神奇数字”

我相信你可以在其他网络服务器上做这类事情

答案 2 :(得分:2)

随意使用此IpRangeFilter类。请参阅课堂评论以获得解释。

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections15.Predicate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * I am a filter used to determine if a given IP Address is covered by the IP range specified in 
 * the constructor.  I accept IP ranges in the form of full single IP addresses, e.g. 10.1.0.23
 * or network/netmask pairs in CIDR format e.g. 10.1.0.0/16
 */
public class IpRangeFilter implements Predicate<InetAddress> {

    private final long network;
    private final long netmask;

    private final String ipRange;

    private static final Pattern PATTERN = Pattern.compile("((?:\\d|\\.)+)(?:/(\\d{1,2}))?");

    public IpRangeFilter(String ipRange) throws UnknownHostException {
        Matcher matcher = PATTERN.matcher(ipRange);
        if (matcher.matches()) {
            String networkPart = matcher.group(1);
            String cidrPart = matcher.group(2);

            long netmask = 0;
            int cidr = cidrPart == null ? 32 : Integer.parseInt(cidrPart);
            for (int pos = 0; pos < 32; ++pos) {
                if (pos >= 32-cidr) {
                    netmask |= (1L << pos);
                }
            }

            this.network = netmask & toMask(InetAddress.getByName(networkPart));
            this.netmask = netmask;
            this.ipRange = ipRange;

        } else {
            throw new IllegalArgumentException("Not a valid IP range: " + ipRange);
        }
    }

    public String getIpRange() {
        return ipRange;
    }

    public boolean evaluate(InetAddress address) {
        return isInRange(address);
    }

    public boolean isInRange(InetAddress address) {
        return network == (toMask(address) & netmask);
    }

    /**
     * Convert the bytes in the InetAddress into a bit mask stored as a long.
     * We could use int's here, but java represents those in as signed numbers, which can be a pain 
     * when debugging.
     * @see http://www.captain.at/howto-java-convert-binary-data.php
     */
    static long toMask(InetAddress address) {
        byte[] data = address.getAddress();
        long accum = 0;
        int idx = 3;
        for ( int shiftBy = 0; shiftBy < 32; shiftBy += 8 ) {
            accum |= ( (long)( data[idx] & 0xff ) ) << shiftBy;
            idx--;
        }
        return accum;
    }
}

答案 3 :(得分:0)

尝试此bug report中的Subnet课程。

答案 4 :(得分:0)

您可以使用以下代码,当然它假设输入数据是正确的,因此它需要一些美化(以防万一)

public class IPUtil
{

    private static int[] split(String ip)
    {
        int[] result = new int[4];
        StringTokenizer st = new StringTokenizer(ip, ".");
        for (int i = 0; i < 4; i++)
        {
            result[i] = Integer.parseInt(st.nextToken());
        }
        return result;
    }

    public static boolean matches(String visitorIpString, String ipString, String maskString)
    {
        int[] vip = split(visitorIpString);
        int[] ip = split(ipString);
        int[] mask = split(maskString);

        for (int i = 0; i < 4; i++)
        {
            if ((vip[i] & mask[i]) != ip[i])
            {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args)
    {

        String ip = "192.168.12.0";
        String mask = "255.255.255.0";
        String visitorIP = "192.168.12.55";

        System.out.println(matches(visitorIP, ip, mask));
    }
}