2

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

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

jpos.JposException:无法打开设备通信通道,请检查设备并重试。

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

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

4

4 回答 4

2

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

Applet.init()在通话的开场白中System.setSecurityManager(null)。然后尝试连接到 USB。

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

请注意,我并不是建议将这样的代码投入生产。如果您的小程序与其他小程序在同一个 JRE 中运行,则取消 SM 还可以提升其他小程序的权限。

于 2011-04-17T19:45:12.473 回答
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,则签名Applet通常会允许这样做。将其包装成 aPrivilegedAction会更好,并且首先使用检查权限AccessController.checkPermission(...)将是理想的。

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

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

为了规避这个问题,有些人选择使用PrivelegedAction,但是如果操作需要很长时间,您会注意到它会阻塞 UI,这在网页中是非常糟糕的做法(并且可能会使浏览器死锁)。

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

此外,您的问题专门询问有关访问 USB 外围设备的问题,这通常是通过迭代人机接口设备来完成的。HID 不是 Java 本身直接支持的东西(然而,在编写此/JRE7 时)。所以是的,一个签名的小程序可以与您的 USB 外围设备对话,但您需要使用某种形式的 Java 本机接口 (JNI) 来正确“访问”它们。JNI 支持跨平台(即用你的 JAR 分发 DLL 和 SO)可能是一团糟,所以......

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

于 2014-03-20T15:17:17.607 回答
1

我在 XP 和 Win7 32bit 上使用 JRE 1.6 的 Epson TM-H6000III 遇到了类似的问题。管理员可以使用该设备,但“用户”不能。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 很快就解决了这个问题。

于 2011-09-28T00:59:02.553 回答
0

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

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

于 2011-05-13T21:23:22.693 回答