3

由于1 月到期的更严格的安全限制7u51我正在尝试签署我的 JNLP 文件。

我们的应用程序需要设置某些自定义系统属性,其中一些属性的值会根据小程序的部署位置而有所不同。我想避免为每个部署重新签署包含 JNLP 模板的 JAR。

放入 JNLP 模板的幼稚方法<property name="my-prop" value="*"/>行不通。

即使<property name="my-prop" value="fixed-value"/>在模板中,有时我也会收到一个对话框,提示“此应用程序将执行不安全的操作。您要继续吗?”:

不安全的操作安全对话框

将系统属性传递给已签名的 Java RIA 的正确方法是什么?

4

1 回答 1

6

在这两个方面,您的应用程序将需要添加一些在启动时执行的琐碎代码,以解决这两个问题。

属性值中不允许使用通配符

JNLP 规范说:

预计 JNLP 客户端会将某些 jnlp 元素和参数值(例如“java-vm-args”或属性“名称”和“值”)列入黑名单(或限制)以维护安全性。确切的列表取决于各个 JNLP 客户端实现。

事实上,Oracle 实现(至少在 7u45 中)确实value将元素的属性列入了黑名单<property/>——它不能使用通配符。我一直无法找到这个决定背后的任何原因,但它确实存在。

webstart 解决方法允许任意属性名称和值;小程序解决方法要求在代码签名时知道属性的名称。

解决方法:Webstart

在您的 JNLP 文件中,包含一些通配符参数:

<application-desc main-class="com.example.YourMainClass">
  <argument>*</argument>
  <argument>*</argument>
</application-desc>

在应用程序的main方法中,解析这些参数并使用 将它们复制到系统属性中System.setProperty(),跳过仍然具有文字值的参数"*"。我建议在第一次出现"=". (如果您的应用程序也已经接受了常规参数,那么您将不得不变得更有创意。)

解决方法:小程序

在您的 JNLP 文件中,包括定义需要设置的系统属性的参数:

<applet-desc main-class="com.example.YourMainClassApplet">
  <param name="SYS_PROPERTY_PARAMETERS" value="prop1,prop2"/>
  <param name="prop1" value="*"/>
  <param name="prop2" value="*"/>
</applet-desc>

在您的Applet.init()方法中,获取SYS_PROPERTY_PARAMETERS参数的值,并对其进行迭代以获取每个参数的值。如果它不是文字"*",则使用 将其复制到系统属性中System.setProperty()

“不安全操作”对话框

这是Oracle 插件中的一个错误,由使用 LiveConnect(Java <-> JavaScript 交互)触发。

解决方法:“安全”属性前缀

<property/>通过JNLP 中的元素设置的所有系统属性的前缀为"jnlp."

<property name="jnlp.my-prop" value="fixed-value"/>

然后在您的应用程序main()Applet.init()方法中,遍历 的副本 System.getProperties(),如果属性名称以 开头,则将"jnlp."其值复制到同名的属性中,并去掉前缀。(迭代副本是必要的以避免ConcurrentModificationException.)

Gotcha:JNLP 模板验证器考虑 XML 属性的顺序

最后,如果您填写属性值的过程可能会导致 JNLP 文档中其他元素的属性重新排序,这可能会导致 JNLP 模板验证失败。(使用 DOM 解析器解析 JNLP,填写通配符,然后使用流式传输将其返回StreamResult是可能发生这种情况的一种方式。)例如,我有这两个多属性元素,并且元素的顺序必须匹配:

<jnlp codebase="*" spec="1.0+">
<j2se java-vm-args="-Xms256M -Xmx512M -XX:MaxPermSize=256m" version="1.6+"/>
于 2013-12-06T17:46:41.690 回答