5

I'm looking for a solution for a Java based webapplication to uniquely identify the client. The server is in the same network as the clients and I thought that using the MAC address would be a good solution. The problem is I can't work with cookies because they can be deleted client-side and I can't use the IP because they could just issue a new DHCP lease renewal.

So I would like to fallback to the MAC address of the clients. I'm aware that there is no java built in feature to get the MAC address. Is there a library that can handle the output of every OS? (primary Windows and Mac) since my java Application runs on both platforms.

or are there any other suggestions for uniquely identifying a client within a website and the HTTP Protocol ? (maybe HTML5 data stores or something else)

I'm using Java 1.7 btw.

I won't force the user to login or otherwise identify himself and I won't program a native app for the clients smartphone.

Victor2748
  • 4,149
  • 13
  • 52
  • 89
Nexus2k
  • 345
  • 1
  • 4
  • 13
  • Here is the answer: "How to get a unique computer identifier in Java (like disk id or motherboard id)" (http://stackoverflow.com/questions/1986732/how-to-get-a-unique-computer-identifier-in-java-like-disk-id-or-motherboard-id) – Igor K Feb 12 '13 at 10:40
  • I'm looking for a uuid of a CLIENT which is only using the webservice. (No Java applets on client involved), your link only involves local computer. – Nexus2k Feb 12 '13 at 10:48

3 Answers3

11

I wrote my own method to solve my issue. Here it is if ever someone needs code to find a MAC address in the same network. Works for me without any admin privileges on Win 7 and Mac OS X 10.8.2

Pattern macpt = null;

private String getMac(String ip) {

    // Find OS and set command according to OS
    String OS = System.getProperty("os.name").toLowerCase();

    String[] cmd;
    if (OS.contains("win")) {
        // Windows
        macpt = Pattern
                .compile("[0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+-[0-9a-f]+");
        String[] a = { "arp", "-a", ip };
        cmd = a;
    } else {
        // Mac OS X, Linux
        macpt = Pattern
                .compile("[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+");
        String[] a = { "arp", ip };
        cmd = a;
    }

    try {
        // Run command
        Process p = Runtime.getRuntime().exec(cmd);
        p.waitFor();
        // read output with BufferedReader
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                p.getInputStream()));
        String line = reader.readLine();

        // Loop trough lines
        while (line != null) {
            Matcher m = macpt.matcher(line);

            // when Matcher finds a Line then return it as result
            if (m.find()) {
                System.out.println("Found");
                System.out.println("MAC: " + m.group(0));
                return m.group(0);
            }

            line = reader.readLine();
        }

    } catch (IOException e1) {
        e1.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // Return empty string if no MAC is found
    return "";
}
Nexus2k
  • 345
  • 1
  • 4
  • 13
  • This is not guaranteed because of this "To be able to ARP a device, you must have an interface (SVI) on that switch on that network. To ARP a device you must have an interface with a layer 3 IP on the same layer 2 vlan." an alternative is to use "getmac /s 00.00.00.00" where 00.00.00.00 is the remote ip address – pedromendessk Aug 31 '15 at 16:58
  • @Nexus2K i used your code it works correctly for windows system but linux it not working why – KVK Nov 17 '15 at 05:39
  • @KVK it works form me under linux mint. If you are requesting from `127.0.0.1` it won't find anything. Implement it! – selan Mar 07 '17 at 15:55
3

The best I could find is this: Query ARP cache to get MAC ID

And the potted summary is that:

  • there is no standard Java API,
  • there is no operating system independent solution,
  • your application typically needs to be privileged (e.g. root access) to query the host's ARP cache, and
  • if the packets go through a network router, you won't be able to identify the source MAC address anymore.

I don't think this is a good approach for identifying your user's machine.

Consider also that:

  • This only identifies the machine, not the user. Some computers are shared by multiple users.
  • MAC addresses can be changed too.
Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • More info about the clients. They are all smartphones which aren't shared over multiple users. Changing the MAC address of smartphones is exponentially harder than deleting cookies. – Nexus2k Feb 12 '13 at 11:59
  • And as stated in the question all clients are in the same network – Nexus2k Feb 12 '13 at 12:14
0

Usage of IP address isn't working in the local network. I have used some other method to get a MAC address - sysout parsing of useful commands.

public String getMacAddress() throws Exception {
    String macAddress = null;
    String command = "ifconfig";

    String osName = System.getProperty("os.name");
    System.out.println("Operating System is " + osName);

    if (osName.startsWith("Windows")) {
        command = "ipconfig /all";
    } else if (osName.startsWith("Linux") || osName.startsWith("Mac") || osName.startsWith("HP-UX")
            || osName.startsWith("NeXTStep") || osName.startsWith("Solaris") || osName.startsWith("SunOS")
            || osName.startsWith("FreeBSD") || osName.startsWith("NetBSD")) {
        command = "ifconfig -a";
    } else if (osName.startsWith("OpenBSD")) {
        command = "netstat -in";
    } else if (osName.startsWith("IRIX") || osName.startsWith("AIX") || osName.startsWith("Tru64")) {
        command = "netstat -ia";
    } else if (osName.startsWith("Caldera") || osName.startsWith("UnixWare") || osName.startsWith("OpenUNIX")) {
        command = "ndstat";
    } else {// Note: Unsupported system.
        throw new Exception("The current operating system '" + osName + "' is not supported.");
    }

    Process pid = Runtime.getRuntime().exec(command);
    BufferedReader in = new BufferedReader(new InputStreamReader(pid.getInputStream()));
    Pattern p = Pattern.compile("([\\w]{1,2}(-|:)){5}[\\w]{1,2}");
    while (true) {
        String line = in.readLine();
        System.out.println("line " + line);
        if (line == null)
            break;

        Matcher m = p.matcher(line);
        if (m.find()) {
            macAddress = m.group();
            break;
        }
    }
    in.close();
    return macAddress;
}

This should work everywhere. At least, the usage of this method on Ubuntu machine gives the following result:

Operating System is Linux
line eth0      Link encap:Ethernet  HWaddr f4:6d:04:63:8e:21  
mac: f4:6d:04:63:8e:21
user1856533
  • 409
  • 4
  • 13