如何在Java中以策略权限运行applet以读取MAC地址

时间:2018-10-31 09:50:30

标签: java applet japplet

我正在尝试在NetBeans中开发一个可以读取MAC地址的小程序。

这是我的目录结构

enter image description here

这是我的更新代码

  

MacAddrApplet.java

import java.awt.Graphics;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.swing.JApplet;

/**
 *
 * @author jay.patel
 */
public class MacAddressApplet extends JApplet {

    public static String getMacFromInterface(NetworkInterface ni) throws SocketException {
        byte mac[] = ni.getHardwareAddress();

        if (mac != null) {
            StringBuilder macAddress = new StringBuilder("");
            String sep = "";
            for (byte o : mac) {
                macAddress.append(sep).append(String.format("%02X", o));
                sep = ":";
            }
            return macAddress.toString();
        }

        return "";
    }

    public static String[] getInterfaces() {
        try {
            Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();

            ArrayList<String> result = new ArrayList<String>();
            while (nis.hasMoreElements()) {
                NetworkInterface ni = nis.nextElement();
                if (ni.isUp() && !ni.isLoopback() && !ni.isVirtual()) {
                    String mac = getMacFromInterface(ni);
                    String str = ni.getDisplayName() + ";" + mac;
                    result.add(str);
                }
            }
            return result.toArray(new String[0]);
        } catch (SocketException e) {
            System.out.println("SocketException:: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Exception:: " + e.getMessage());
        }

        return new String[0];
    }

    public static String getInterfacesJSON() {
        try {
            String macs[] = getInterfaces();

            String sep = "";
            StringBuilder macArray = new StringBuilder("['");
            for (String mac : macs) {
                macArray.append(sep).append(mac);
                sep = "','";
            }
            macArray.append("']");

            return macArray.toString();
        } catch (Exception e) {
            System.out.println("Exception:: " + e.getMessage());
        }

        return "[]";
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
         AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                String macs[] = getInterfaces();

                for (String mac : macs) {
                    System.out.println(" Interfaces = " + mac);
                }

                System.out.println(" Interfaces JSON = " + getInterfacesJSON());
                g.drawString("MAC: " + getInterfacesJSON(), 100, 100);
                return null;
            }
        });

    }

}
  

MacAddrApplet.html

<HTML>
<HEAD>
    <TITLE>Applet HTML Page</TITLE>
</HEAD>
<BODY>

    <H3><HR WIDTH="100%">Applet HTML Page<HR WIDTH="100%"></H3>

    <P><APPLET codebase="classes" code="MacAddrApplet.class" width=350 height=200></APPLET></P>

    <HR WIDTH="100%"><FONT SIZE=-1><I>Generated by NetBeans IDE</I></FONT>
</BODY>

  

applet.policy

grant {
permission java.security.AllPermission;
};

当我尝试从Run -> Run File运行applet时,它运行正常,并在其中显示了我的Mac地址,并显示了我正在打印的日志

Interfaces = en1;XX:XX:XX:XX:XX:XX
Interfaces JSON = ['en1;XX:XX:XX:XX:XX:XX']

但是当我尝试使用

运行它时
appletviewer build/MacAddrApplet.html

它打印

Interfaces = en1;
Interfaces JSON = ['en1;']

如何解决此问题?

P.S。我认为是因为它没有使用applet.policy

的权限

2 个答案:

答案 0 :(得分:2)

最终,我发现了终端命令出了什么问题

appletviewer build/MacAddrApplet.html

由于您看到位于project.properties文件夹中的nbproject文件,因此在结尾部分,您将看到

run.jvmargs=-Djava.security.policy=applet.policy

因此,当我使用Run -> Run File运行applet时,Netbeans内部会处理所有事情,因此applet运行得很好。

但是,在终端的情况下,我需要显式指定policy file(这是我问问题时要知道的内容!),因此运行applet此命令,它将正常工作...

appletviewer -J-Djava.security.policy=applet.policy build/MacAddrApplet.html

答案 1 :(得分:1)

这不一定与Applet权限有关。这主要是代码中的一个很好的老式错误:-)。

阅读NetworkInterface.getHardwareAddress()的文档-该方法可能返回null

  

返回:包含地址的字节数组;如果地址,则返回null   不存在,不可访问或设置了安全管理器,并且   呼叫者没有权限   NetPermission(“ getNetworkInformation”)

调用时您忘记了空检查,因此忘记了NullPointerException。

关于为什么,您回来了null-这可能是由于SecurityManager(如文档所示),但是在这种情况下,问题可能是InetAddress.getLocalHost()给了您localhost地址,因此您得到的接口是回送接口。环回接口(作为模拟接口)没有MAC地址,因此NetworkInterface.getHardwareAddress()将返回null


向后退一步,您的第一个错误是使用InetAddress.getLocalHost()。一台计算机可以具有多个具有多个IP地址的网络接口(例如,有线以太网接口和WLAN接口,以及虚拟接口(例如环回)或VPN客户端)。 因此,通常不存在“ MAC地址”,而是0-n个MAC地址,具体取决于系统配置。

您需要弄清楚如何选择可用的MAC地址。您可以使用NetworkInterface.getNetworkInterfaces()来检索系统具有的所有接口(甚至是已停用的接口),然后遍历它们来确定您喜欢的接口(以及哪个接口具有MAC地址)。