Kennt jemand eine Java-Komponente zu überprüfen, ob die IP-Adresse von bestimmtem Netzwerk / netmask ist? [geschlossen]

StackOverflow https://stackoverflow.com/questions/577363

  •  05-09-2019
  •  | 
  •  

Frage

ich brauche, um zu bestimmen, ob bestimmte IP-Adresse von einem speziellen Netzwerk ist i automatisch authentifizieren muss.

War es hilfreich?

Lösung

Apache Commons Net org.apache.commons.net.util.SubnetUtils hat, die Ihren Bedürfnissen gerecht zu werden scheint. Es sieht aus wie Sie etwas tun:

SubnetInfo subnet = (new SubnetUtils("10.10.10.0", "255.255.255.128")).getInfo();
boolean test = subnet.isInRange("10.10.10.10");

Beachten Sie, wie carson weist darauf hin, dass Apache Commons Net hat

Andere Tipps

Option 1:

Verwenden Sie spring-security-web 's IpAddressMatcher . Im Gegensatz zu Apache Commons Net unterstützt es sowohl IPv4- als auch IPv6.

import org.springframework.security.web.util.matcher.IpAddressMatcher;
...

private void checkIpMatch() {
    matches("192.168.2.1", "192.168.2.1"); // true
    matches("192.168.2.1", "192.168.2.0/32"); // false
    matches("192.168.2.5", "192.168.2.0/24"); // true
    matches("92.168.2.1", "fe80:0:0:0:0:0:c0a8:1/120"); // false
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/120"); // true
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/128"); // false
    matches("fe80:0:0:0:0:0:c0a8:11", "192.168.2.0/32"); // false
}

private boolean matches(String ip, String subnet) {
    IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(subnet);
    return ipAddressMatcher.matches(ip);
}

Option 2 (eine leichte Lösung!):

Der Code in vorherigem Teil funktioniert völlig in Ordnung , aber es braucht spring-security-web aufgenommen werden.

Wenn Sie nicht bereit sind, zu Spring-Framework in Ihrem Projekt enthält, können Sie diese Klasse verwenden, das ist eine leicht modifizierte Version des Original-Klasse aus Spring, so dass es keine nicht hat -jdk Abhängigkeiten.

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Matches a request based on IP Address or subnet mask matching against the remote
 * address.
 * <p>
 * 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
 * 
 * Slightly modified by omidzk to have zero dependency to any frameworks other than the JDK.
 */
public final class IpAddressMatcher {
    private final int nMaskBits;
    private final InetAddress requiredAddress;

    /**
     * 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).
     *
     * @param ipAddress the address or range of addresses from which the request must
     * come.
     */
    public IpAddressMatcher(String ipAddress) {

        if (ipAddress.indexOf('/') > 0) {
            String[] addressAndMask = ipAddress.split("/");
            ipAddress = addressAndMask[0];
            nMaskBits = Integer.parseInt(addressAndMask[1]);
        }
        else {
            nMaskBits = -1;
        }
        requiredAddress = parseAddress(ipAddress);
        assert  (requiredAddress.getAddress().length * 8 >= nMaskBits) :
                String.format("IP address %s is too short for bitmask of length %d",
                        ipAddress, nMaskBits);
    }

    public boolean matches(String address) {
        InetAddress remoteAddress = parseAddress(address);

        if (!requiredAddress.getClass().equals(remoteAddress.getClass())) {
            return false;
        }

        if (nMaskBits < 0) {
            return remoteAddress.equals(requiredAddress);
        }

        byte[] remAddr = remoteAddress.getAddress();
        byte[] reqAddr = requiredAddress.getAddress();

        int nMaskFullBytes = nMaskBits / 8;
        byte finalByte = (byte) (0xFF00 >> (nMaskBits & 0x07));

        // System.out.println("Mask is " + new sun.misc.HexDumpEncoder().encode(mask));

        for (int i = 0; i < nMaskFullBytes; i++) {
            if (remAddr[i] != reqAddr[i]) {
                return false;
            }
        }

        if (finalByte != 0) {
            return (remAddr[nMaskFullBytes] & finalByte) == (reqAddr[nMaskFullBytes] & finalByte);
        }

        return true;
    }

    private InetAddress parseAddress(String address) {
        try {
            return InetAddress.getByName(address);
        }
        catch (UnknownHostException e) {
            throw new IllegalArgumentException("Failed to parse address" + address, e);
        }
    }
}

Diff:

+ * 
+ * Slightly modified by omidzk to have zero dependency to any frameworks other than the JDK.

-import javax.servlet.http.HttpServletRequest;
-
-import org.springframework.security.web.util.matcher.RequestMatcher;
-import org.springframework.util.StringUtils;
-import org.springframework.util.Assert;

-public final class IpAddressMatcher implements RequestMatcher {
+public final class IpAddressMatcher {

-           String[] addressAndMask = StringUtils.split(ipAddress, "/");
+           String[] addressAndMask = ipAddress.split("/");

-       Assert.isTrue(requiredAddress.getAddress().length * 8 >= nMaskBits,
+       assert  (requiredAddress.getAddress().length * 8 >= nMaskBits) :

-                       ipAddress, nMaskBits));
+                       ipAddress, nMaskBits);

-
-   public boolean matches(HttpServletRequest request) {
-       return matches(request.getRemoteAddr());
-   }

ACHTUNG: : Beachten Sie, dass diese Option für die Nutzung, ist es in Ihrer Verantwortung, sorgfältig die Lizenz um sicherzustellen, dass durch diesen Code verwenden, sind Sie nicht in der Verletzung von Bedingungen durch die zuvor genannte Lizenz vorgeschrieben ist. (Natürlich Veröffentlichung diesen Code Stackoverflow.com von mir nicht eine Verletzung).

Sie können auch versuchen

boolean inSubnet = (ip & netmask) == (subnet & netmask);

oder kürzer

boolean inSubnet = (ip ^ subnet) & netmask == 0;

Die Open-Source-Java-Bibliothek IPAddress diese in einer polymorphen Weise für IPv4 tun und IPv6 und Griffe Subnetze. Disclaimer: Ich bin der Projektleiter dieser Bibliothek

.

Beispielcode:

contains("10.10.20.0/30", "10.10.20.3");
contains("10.10.20.0/30", "10.10.20.5");
contains("1::/64", "1::1");
contains("1::/64", "2::1");
contains("1::3-4:5-6", "1::4:5");       
contains("1-2::/64", "2::");
contains("bla", "foo");

static void contains(String network, String address) {
    IPAddressString one = new IPAddressString(network);
    IPAddressString two = new IPAddressString(address);
    System.out.println(one +  " contains " + two + " " + one.contains(two));
}

Ausgabe:

10.10.20.0/30 contains 10.10.20.3 true
10.10.20.0/30 contains 10.10.20.5 false
1::/64 contains 1::1 true
1::/64 contains 2::1 false
1::3-4:5-6 contains 1::4:5 true
1-2::/64 contains 2:: true
bla contains foo false

Eine IP in einem Sub-Netz zu überprüfen, habe ich isInRange Methode in SubnetUtils Klasse. Aber diese Methode hat einen Fehler, wenn Ihr Subnetz ist X, jede IP-Adresse, die niedriger ist als X, isInRange true zurück. Zum Beispiel, wenn Ihr Subnetz war 10.10.30.0/24 und Sie mögen 10.10.20.5 überprüfen, diese Methode true zurück. Um mit diesem Fehler, den ich unten Code verwendet wird.

public static void main(String[] args){
    String list = "10.10.20.0/24";
    String IP1 = "10.10.20.5";
    String IP2 = "10.10.30.5";
    SubnetUtils  subnet = new SubnetUtils(list);
    SubnetUtils.SubnetInfo subnetInfo = subnet.getInfo();
    if(MyisInRange(subnetInfo , IP1) == true)
       System.out.println("True");
    else 
       System.out.println("False");
    if(MyisInRange(subnetInfo , IP2) == true)
       System.out.println("True");
    else
       System.out.println("False");
}

private boolean MyisInRange(SubnetUtils.SubnetInfo info, String Addr )
{
    int address = info.asInteger( Addr );
    int low = info.asInteger( info.getLowAddress() );
    int high = info.asInteger( info.getHighAddress() );
    return low <= address && address <= high;
}

Hier ist eine Version, die mit IPv4 und IPv6 einem mit Präfix und ein mit Netzwerkmaske funktioniert.

/**
 * Check if IP is within an Subnet defined by Network Address and Network Mask
 * @param  ip
 * @param  net
 * @param  mask
 * @return
 */
public static final boolean isIpInSubnet(final String ip, final String net, final int prefix) {
    try {
        final byte[] ipBin   = java.net.InetAddress.getByName(ip  ).getAddress();
        final byte[] netBin  = java.net.InetAddress.getByName(net ).getAddress();
        if(ipBin.length  != netBin.length ) return false;
        int p = prefix;
        int i = 0;
        while(p>=8) { if(ipBin[i] != netBin[i] ) return false; ++i; p-=8; }
        final int m = (65280 >> p) & 255;
        if((ipBin[i] & m) != (netBin[i]&m) ) return false;

        return true;
    } catch(final Throwable t) {
        return false;
    }
}

/**
 * Check if IP is within an Subnet defined by Network Address and Network Mask
 * @param  ip
 * @param  net
 * @param  mask
 * @return
 */
public static final boolean isIpInSubnet(final String ip, final String net, final String mask) {
    try {
        final byte[] ipBin   = java.net.InetAddress.getByName(ip  ).getAddress();
        final byte[] netBin  = java.net.InetAddress.getByName(net ).getAddress();
        final byte[] maskBin = java.net.InetAddress.getByName(mask).getAddress();
        if(ipBin.length  != netBin.length ) return false;
        if(netBin.length != maskBin.length) return false;
        for(int i = 0; i < ipBin.length; ++i) if((ipBin[i] & maskBin[i]) != (netBin[i] & maskBin[i])) return false;
        return true;
    } catch(final Throwable t) {
        return false;
    }
}

Ich weiß, das sehr alte Frage, aber ich gestolpert, als ich war auf der Suche das gleiche Problem zu lösen.

Es gibt commons-ip-math Bibliothek, die ich glaube, eine sehr gut tut Job. Bitte beachten Sie, dass ab Mai 2019 hat es nicht in die Bibliothek alle Updates waren (dass seine bereits sehr ausgereift Bibliothek sein könnte). Seine auf Maven-central

Es unterstützt sowohl IPv4 als auch IPv6-Adressen arbeiten. Ihre kurze Dokumentation hat Beispiele, wie Sie überprüfen können, ob eine Adresse in einem bestimmten Bereich ist IPv4 und IPv6

Beispiel für IPv4 Bereichsprüfung:

        String input1 = "192.168.1.0";
        Ipv4 ipv41 = Ipv4.parse(input1);

        // Using CIDR notation to specify the networkID and netmask
        Ipv4Range range = Ipv4Range.parse("192.168.0.0/24");
        boolean result = range.contains(ipv41);
        System.out.println(result); //false

        String input2 = "192.168.0.251";
        Ipv4 ipv42 = Ipv4.parse(input2);

        // Specifying the range with a start and end.
        Ipv4 start = Ipv4.of("192.168.0.0");
        Ipv4 end = Ipv4.of("192.168.0.255");
        range = Ipv4Range.from(start).to(end);

        result = range.contains(ipv42); //true
        System.out.println(result);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top