JNLP:在签名代码中加载未签名的代码

时间:2012-04-19 20:39:57

标签: java classloader code-signing jnlp

我们在克服Java webstart的混合代码错误时遇到了困难。总之,我们有我们的主要JNLP文件,我们已经签署了它直接加载的所有代码。我们已将all-permissions选项添加到主JNLP中。它加载的主要类也来自一个签名的jar。

当主要课程开始时,它会触发一些需要加载从JNLP B中提取的未签名资源的东西。没有JNLP B的资源被签名且它们不需要任何特殊权限。

所有已签名的代码都是基于Oracle的混合代码文档设置的,并且jar文件在签名之前已经设置了“Trusted-Library:true”的清单。

当尝试通过签名代码加载未签名的代码时,我们得到一个类未找到错误,如下所示:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

    Caused by: java.lang.NoClassDefFoundError: org/some/external/package/that/is/not/signed
at org.our.signed.package.main(Main.java:87)
... 9 more

    Caused by: java.lang.ClassNotFoundException: org.some.external.package.that.is.not.signed
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 10 more

以下是JNLP中的情景:

JNLP答:(总结)

<jnlp spec="1.5+" codebase="...." href="......">
  <information>
   ...etc
  </information>
   <security>
     <all-permissions/>
   </security>
   <resources>
      <j2se version="1.6+" initial-heap-size="80m" max-heap-size="256m" href="http://java.sun.com/products/autodl/j2se"/>
      <jar href="signedJar_1.jar" download="eager" main="true"/>
      <jar href="signedJar_2.jar" download="eager" main="false"/>
      <extension name="unsigned_ext" href="unsigned.jnlp"/>
  </resources>
  <application-desc main-class="(FROM SIGNED CLASS in signedJar_1.jar)"/>
</jnlp>

JNLP B(unsigned.jnlp加载程序)

<jnlp spec="1.5+" codebase="....." href="......">
  <information>
   ...etc
  </information>
  <resources>
    <jar href="unsigned.jar"/>
  </resources>
  <component-desc/>
</jnlp>

我们已经注意到安全异常正常工作,因为如果我们将未签名的jar移动到具有所有权限且已签名jar的JNLP中,我们会得到Java不会让我们混合的预期安全异常使用Trusted-Library签名的代码:true和unsigned代码,没有manifest属性。

想法?是否有理由类加载器无法从无符号代码中找到java文件?有没有什么特别的东西我们缺少允许签名代码运行未签名的代码?我只看到了人们在使用未签名的代码运行签名代码时遇到问题的情况,我可以理解。

1 个答案:

答案 0 :(得分:5)

可信库类加载器是(可能是不受信任的)applet类加载器的父类(在类加载器委托的意义上)。把它想象成是引导类加载器。因此,不受信任的类可以链接到可信库类,但反之亦然。无需更改清单和使用WebStart,您可以通过添加-Xbootclasspath/a:的受信任类和-classpath不受信任的类来尝试这些内容(这是该功能在之前的尝试方式)实现)。

JNLPAppletLauncher是如何让信任库调用applet代码的示例。可以使用Thread.currentThread().getContextClassLoader()获取applet类加载器,它只是从那里反射出来的。编写安全的可信库代码很棘手。请记住,您不能信任不受信任的代码。