Ho bisogno di determinare se l'indirizzo IP dato proviene da qualche rete speciale devo autenticarmi automaticamente.Qualcuno conosce un componente java per verificare se l'indirizzo IP proviene da una particolare rete/maschera di rete?
risposta
Jakarta Commons Net ha org.apache.commons.net.util.SubnetUtils
che sembra soddisfare le vostre esigenze. Sembra che si fa qualcosa di simile:
SubnetInfo subnet = (new SubnetUtils("10.10.10.0", "255.255.255.128")).getInfo();
boolean test = subnet.isInRange("10.10.10.10");
nota, come carson sottolinea, che Jakarta Commons Net ha a bug che gli impedisce di dare la risposta corretta in alcuni casi. Carson suggerisce di usare la versione SVN per evitare questo bug.
Si può anche provare
boolean inSubnet = (ip & netmask) == (subnet & netmask);
o meno lungo
boolean inSubnet = (ip^subnet) & netmask == 0;
Sono ip o netmask inte o long? – simgineer
Gli indirizzi a 32 bit, IPv4, sono ints. Ho il sospetto che IPv6 sia un valore a 64 bit, ma non ho usato me stesso –
Usa Primavera IpAddressMatcher. A differenza di Apache Commons Net, supporta sia ipv4 che 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);
}
Fonte: here
Per controllare un IP in una sottorete, ho usato il metodo isInRange in classe SubnetUtils. Ma questo metodo ha un bug che se la tua sottorete era X, ogni indirizzo IP inferiore a X, isInRange restituisce true. Ad esempio se la tua sottorete era 10.10.30.0/24 e vuoi controllare 10.10.20.5, questo metodo restituisce true. Per far fronte a questo bug ho usato il codice qui sotto.
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;
}
Fare attenzione a questo. C'è un bug che impedirà il corretto funzionamento. Potresti voler estrarlo da SVN. http://mail-archives.apache.org/mod_mbox/commons-issues/200902.mbox/%[email protected]%3E – carson
@carson: Grazie per l'avvertimento. Ho modificato la mia risposta per includere questa informazione. – Eddie