在浏览器沙箱中运行时,签名的Java applet是否可以访问USB外围设备?

时间:2011-04-17 15:20:50

标签: java applet usb javapos

我已经实现了一个Java软件包,其功能是通过USB连接到工作站的POS打印机和现金抽屉。我还实现了一个applet来利用这个软件包的功能,希望能够通过POS网站调用它。

当从Eclipse中运行applet时,一切顺利。当applet在浏览器中运行时,我的软件包似乎无法访问通过USB连接的外围设备。我收到来自第三方(JavaPOS)代码的错误说明:

  

jpos.JposException:设备   沟通渠道不可能   打开,检查设备并重试。

小程序使用自我证书进行签名。我发布了一些代码,但错误是从埋在制造商专用驱动程序中的某个地方抛出的,用于正在使用的POS打印机。

我假设问题是,在浏览器沙箱中,applet无法访问通过USB连接的外围设备。
可能是这种情况吗?如果是这样,无论如何都要从已签名的Applet中访问USB外围设备? 如果applet无法访问USB外围设备,那么网站如何调用可以使用的代码?

4 个答案:

答案 0 :(得分:2)

我不确定你问题的答案,但有一个实验可以进一步阐明这个问题。

Applet.init()来电System.setSecurityManager(null)的开头行。然后尝试连接USB。

  • 如果applet受信任,则对setSecurityManager(null)的调用将成功,并删除SecurityManager的最后一个残余。 (是的,即使是受信任的applet也有安全管理器,它对沙盒应用程序的安全管理器的限制要小得多。)
  • 如果现在发现USB,则表示受信任的安全管理器发生了更改。最近有一些这样的变化。

请注意我不建议将此类代码投入生产。如果您的applet与其他applet在同一个JRE中运行,则使SM无效也可以提升其他applet的权限。

答案 1 :(得分:2)

  

在浏览器沙箱中运行时,已签名的Java小程序是否可以访问USB外围设备?

要解决此特定问题(并避免以下评论中涉及的特定技术),是签名Java小程序可以访问USB外设。当您运行已签名的小程序时,“沙箱”就是您“脱离”的能力。

但出于安全原因,只需签署小程序就不会自动授予对沙箱外部项目的访问权限。

PrivelegedAction似乎是访问特权系统组件(如打印机)的首选方法。 Oracle提供了有关这些特权操作的更多信息:http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html

此外,在Web浏览器中执行此类操作时需要考虑几个因素,因为Java会关注操作的来源。

public function writeFile() {
    ...
    FileWriter fw = new FileWriter(...);
    ...
}


public void init() {
    writeFile();
}

例如,如果您要使用applet init()方法中的$HOME/Desktop/text.txt类将文件写入文件系统(即FileWriter),则签名小程序通常 允许它。将其整合到PrivilegedAction会更好,首先使用AccessController.checkPermission(...)检查权限是理想的。

但是,当FileWriter直接从JavaScript(而不是从init())调用时,var myapplet = document.getElementById('myapplet'); myapplet.writeFile(); // Blocked by Security Framework 会被阻止:

PrivelegedAction

为了避免这个问题,有些人选择使用public void init() { ... AccessController.doPrivileged(new PrivilegedAction() { public Object run() { writeFile(); return null; } }); ... } ,但是如果操作需要很长时间,你会注意到它会阻止UI,这在网页中是非常糟糕的做法(并且会使浏览器)。

{{1}}

此外,您的问题具体涉及访问USB外围设备,这通常通过迭代人机接口设备来完成。 HID不是Java本身直接支持的东西(但是,在写这个/ JRE7时)。所以,是的,签名的小程序可以与您的USB外围设备进行通信,但您需要使用某种形式的Java Native Interfacing(JNI)来正确“访问”它们。 JNI可能是一个混乱,以支持跨平台(即与您的JAR分发DLL和SO)所以......

大多数Java Applet所做的是访问本地安装的打印机并使用标准的Java Printing库。这是我们在qz-print项目中执行此操作的方法,您可以在此处查看我们的源代码:https://github.com/qzindustries/qz-print/tree/master/qz-print/src/qz,它使用由init()触发的线程和布尔标志来触发所有特权函数。

答案 2 :(得分:1)

我在XP上使用Epson TM-H6000III和使用JRE 1.6在Win7 32bit上遇到了类似的问题。管理员可以使用该设备,但“用户”不能。 Java控制台正在报告:

Sep 23, 2011 3:38:47 PM com.xxxx.printer.epson.EpsonPrinter findPrinter
INFO: Error opening PrinterIII: jpos.JposException: 
    Could not connect to service with logicalName = 
    PrinterIII: Exception.message=Property or stream open error.

JRE安装似乎有权限问题。重新安装JRE很快就解决了问题。

答案 3 :(得分:0)

我收到了Star Micronics团队的反馈,他们的...... javapos驱动程序不支持网络浏览器打印。'

BTW,System.setSecurityManager(null)被证明是消除我所遇到的与安全相关的任何问题的好方法。谢谢安德鲁。