在浏览器沙箱中运行时,签名的 Java 小程序是否可以访问 USB 外围设备? [英] Do signed java applets have access to USB peripherals when run in the browser sandbox?

查看:31
本文介绍了在浏览器沙箱中运行时,签名的 Java 小程序是否可以访问 USB 外围设备?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个 Java 包,该包具有操作通过 USB 连接到工作站的 POS 打印机和现金抽屉的功能.我还实现了一个小程序来利用这个包的功能,希望能被 POS 网站调用.

I've implemented a Java package with functionality to operate a POS printer and cash drawer connected to the workstation via USB. I've also implemented an applet to utilize the functionality of this package with the hopes of having it invoked by a POS website.

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

When the applet is run from within Eclipse, all goes well. When the applet is run from within a browser it seems that my package is unable to access the peripherals connected via USB. I get an error from the third party (JavaPOS) code stating:

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

jpos.JposException: The device communications channel could not be opened, check the device and retry.

小程序使用自证书签名.我会发布一些代码,但错误是从埋在使用中的 POS 打印机的制造商特定驱动程序中的某个地方抛出的.

The applet is signed with a self-cert. I'd post some code but the error is thrown from somewhere buried in manufacturer-specific drivers for the POS printer in use.

我假设问题是,在浏览器沙箱中,小程序无法访问通过 USB 连接的外围设备.
可能是这种情况吗?如果是这样,是否可以从已签名的 Applet 中访问 USB 外围设备?
如果小程序无法访问 USB 外围设备,网站如何调用可以访问的代码?

I'm assuming the issue is that, from within the browser sandbox, the applet does not have access to the peripherals connected via USB.
Could this be the case? If so, is there anyway to access USB peripherals from within a signed Applet?
If an applet can't access USB peripherals, how could a web site invoke code that can?

推荐答案

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

Do signed java applets have access to USB peripherals when run in the browser sandbox?

为了解决这个特定问题(并避免以下评论中涉及的特定技术),是的,签名 Java 小程序可以访问 USB 外设.沙箱"是您在运行签名小程序时能够摆脱"的东西.

To address this specific question (and avoid the specific technologies involved in the comments following), yes Signed Java Applets have access to USB Peripherals. The "sandbox" is what you have capability to "break out of" when you run a signed applet.

但出于安全原因,仅对小程序进行签名并不会自动授予对沙箱外项目的访问权限.

But for security reasons, simply signing the applet does not automatically give access to items outside of the sandbox.

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

PrivelegedAction seems to be the preferred method for accessing privileged system components, such as the printer. More about these privileged actions is provided by Oracle here: http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html

此外,当从 Web 浏览器执行此类操作时,有几个考虑因素,因为 Java 关心操作的来源.

In addition, there are several consideration when doing something like this from a web browser as Java cares where the action originates from.

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


public void init() {
    writeFile();
}

例如,如果您要使用小程序 init() 方法,签名小程序通常会允许它.将其包装到 PrivilegedAction 中会更好,首先使用 AccessController.checkPermission(...) 检查权限将是理想的.

For example, if you were to write a file to the filesystem (i.e. $HOME/Desktop/text.txt) using the FileWriter class in the applet init() method, a Signed Applet would generally allow it. Wrapping this into a PrivilegedAction would be better, and checking permission first using AccessController.checkPermission(...) would be ideal.

但是,当 FileWriter 直接从 JavaScript(而不是从 init())调用时,它会被阻止:

However, FileWriter gets blocked when it's called directly from JavaScript (instead of from init()):

var myapplet = document.getElementById('myapplet');
myapplet.writeFile(); // Blocked by Security Framework

为了规避这个问题,有些人选择使用 PrivelegedAction,但是如果这个动作需要很长时间,你会发现它会阻塞 UI,这在网页中是非常糟糕的做法(和可以死锁浏览器).

To circumvent this issue, some chose to use PrivelegedAction, however if the action takes a long time, you'll notice it blocks the UI, which is very bad practice in a web page (and can deadlock the browser).

public void init() {
   ...
   AccessController.doPrivileged(new PrivilegedAction() {
      public Object run() {
         writeFile();
         return null;
      }
   });
   ...
}

此外,您的问题特别涉及访问 USB 外围设备,这通常是通过迭代人机接口设备来完成的.HID 不是 Java 本身直接支持的(但是,在编写此/JRE7 时).所以是的,签名的小程序可以与您的 USB 外围设备通信,但您需要使用某种形式的 Java 本地接口 (JNI) 来正确访问"它们.JNI 支持跨平台(即使用 JAR 分发 DLL 和 SO)可能是一团糟,所以...

Furthermore, your question asks specifically about accessing a USB peripheral, which is generally done by iterating through the Human Interface Devices. HID is not something Java directly supports natively (yet, as of writing this/JRE7). So yes, a signed applet CAN talk to your USB peripherals, but you would need to use some form of Java Native Interfacing (JNI) to properly "access" them. JNI can be a mess to support cross-platform (i.e. distributing DLLs and SOs with your JAR) so...

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

What most Java Applets do is access the locally installed printers and use the standard Java Printing libraries. This is how we do it over at the qz-print project and you're free to review our source code here: https://github.com/qzindustries/qz-print/tree/master/qz-print/src/qz which uses threads fired by init() and boolean flags to fire all privileged functions.

这篇关于在浏览器沙箱中运行时,签名的 Java 小程序是否可以访问 USB 外围设备?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆