【问题标题】:AccessControlException when starting embedded Tomcat from Java Webstart从 Java Webstart 启动嵌入式 Tomcat 时出现 AccessControlException
【发布时间】:2012-04-07 12:47:09
【问题描述】:

对于我们的Kunagi Java Web 应用程序,我们有一个签名的kunagi.jar 文件,其中包含我们的类以及来自嵌入式 Tomcat 6 的类。当调用 java -jar kunagi.jar 时,它可以完美运行。

但是当使用 Java WebStart 启动它时,当嵌入式 Tomcat 启动时出现异常:

java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.org.apache.catalina.deploy)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:393)
    at java.security.AccessController.checkPermission(AccessController.java:553)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1529)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:291)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader.loadClass(JNLPClassLoader.java:1018)
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)
    at java.lang.Class.getMethod0(Class.java:2687)
    at java.lang.Class.getMethod(Class.java:1620)
    at org.apache.catalina.startup.SetPublicIdRule.begin(WebRuleSet.java:639)
    at org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1276)
    ... 33 more

当然kunagi.jar 已签名,否则它甚至不会启动。它接缝 Java WebStart 全局启用 Java 安全性,它以某种方式嵌入了 Tomcat“继承”并且无法初始化。

这是 JNLP 文件:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://kunagi.org/webstart" href="kunagi.jnlp">
    <information>
        <title>Kunagi</title>
        <vendor>Kunagi Team</vendor>
        <homepage href="http://kunagi.org"/>
        <description>SCRUM Tool</description>
        <description kind="short">SCRUM Tool</description>
        <offline-allowed/>
    </information>
    <security>
        <all-permissions/>
    </security>
    <resources>
        <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="kunagi.jar" main="true" />
    </resources>
    <application-desc name="Kunagi" main-class="katokorbo.Katokorbo"/>
    <update check="always"/>
</jnlp>

有没有办法在 Java WebStart 中禁用 Tomcat 的安全检查?或者如何配置嵌入式 Tomcat 以允许访问 org.apache.catalina...

【问题讨论】:

    标签: java security tomcat java-web-start


    【解决方案1】:

    解决方案是对要求获得信任的许可的 jar 进行数字签名。任何未签名且不需要信任的内容都需要移至扩展 JNLP。

    【讨论】:

    • 只有一个罐子(kunagi.jar)。它包含 Kunagi 类和所有必需的 Tomcat 类。已签名。
    • JNLP 文件的内容是什么?将其作为问题的编辑发布。
    【解决方案2】:

    公平地说,这似乎是 Tomcat 中的一个错误,您应该报告它。它不应该尝试获取另一个包中的类的方法,因为这在安全管理器下总是会失败。

    在可以修复错误之前,您不能避免调用“WebRuleSet”吗?我不知道它实际上是什么,但它似乎会因为您的 Tomcat 配置而被调用。这不是您可以从配置中删除的东西吗?

    【讨论】:

    • 什么会让你这么说?
    • 您声称 Tomcat 中存在错误。我不相信你已经展示了任何证据来支持这一点。 Tomcat 正在按预期运行。
    • 好吧,正如我写的那样,“它不应该尝试获取另一个包中的类的方法,因为在安全管理器下这总是会失败”,并且 Tomcat 应该是能够在安全管理器下运行。
    • 这个说法是错误的。你认为 Tomcat 包含多少个包?您是否认为整个 Tomcat 的代码都在一个包中?如果你的说法是准确的,Tomcat应该如何访问例如包javax.servlet中的类?
    • 你是在解释我说不能调用其他包中的方法吗?我的意思是不能自省其他包中的类。为了限定语句,类的方法不能被自省,除非调用者的 ClassLoader 是自省类的 ClassLoader 的祖先,或者 SecurityManager 明确允许它。因此,如果 Tomcat 应该在 SecurityManager 下工作(它就是这样),它不应该在不保护 SecurityException 的情况下自省潜在的外部类。
    【解决方案3】:

    Tomcat 在各个地方实施安全管理器访问规则。相关的策略定义可以在 tomcat/conf/catalina.policy 中找到。

    如果 a) 安全管理器已打开,并且 b) 未应用所需的策略文件,则不是 Tomcat 中的错误。

    当然,Tomcat 包含各种包中的代码,当然它使用这些包中的类是正常的。

    更新:在我的沙箱中运行您的 JNLP 应用程序没有问题。 Tomcat 启动成功,除了一些与您描述的无关的异常。我会尝试删除任何以前下载的文件并尝试从缓存中清除所有证书。

    我还建议升级到最新版本的 Tomcat 6.0。

    【讨论】:

    • 但也许这是一个错误,当通过 WebStart 启动时,Tomcat 会自动打开安全管理器?不应该有一个单独的开关吗?
    • WebStart 与 SecurityManager 一起运行。然后Tomcat需要权限才能正常运行。由于使用了 PrivilegedAction,Tomcat 代码已准备好与 SecurityManager 一起运行。
    • 所以这可能是 WebStart 中的一个错误?我已授予我的 WebStart 应用程序的所有权限,但显然它拒绝访问 Tomcat 类。
    • 如其他地方所述,Tomcat 不会打开 SecurityManager。
    • @Witek:我认为问题是以下两件事之一:1)您没有正确配置“所有权限”或 2)WebStart 根本不允许“所有权限”,但只有一个它们的严格子集。您可能想要更多地阅读有关 WebStart 的内容。 Tomcat 本身在 SecurityManager 下运行良好——只要应用了正确的策略。
    【解决方案4】:

    @Witek:Tomcat 不会打开 SecurityManager:JVM 必须在启用了 SecurityManager 并准备好策略文件的情况下启动。 Tomcat 在 SecurityManager 就位后很长时间才会启动。

    【讨论】:

      【解决方案5】:

      Tomcat 似乎已使用其权限来修改全局状态(此处为 package.access 安全属性)。签名的 jar 可以在不受信任的代码共享的进程中运行。您真的不想将两者混合在一起。因此,这里使用的 Tomcat 看起来并不适合 WebStart。

      (Oracle JRE 确实具有安全检查跟踪功能 - -Djava.security.debug=all, IIRC)。

      【讨论】:

      • 有什么证据表明Tomcat使用了它的权限来修改全局状态?
      • @Pidster java.lang.RuntimePermission accessClassInPackage.org.apache.catalina.deploy 我不记得在 JRE 中被限制访问的包。它也在源代码中。
      • 如果 SecurityManager 已打开,Tomcat 会在其代码的各个位中执行额外的访问控制检查——这就是这里发生的所有事情。
      【解决方案6】:

      java.security.AccessControlException:访问被拒绝(java.lang.RuntimePermission accessClassInPackage.org.apache.catalina.deploy)

      每当您收到AccessControlException 时,括号中的部分就是您需要在 .policy 文件中授予的权限,或者,当您使用 JWS 时,在部署描述符中授予权限。

      【讨论】:

        【解决方案7】:

        我的问题已解决如下:

        在 WebStart 启动我的应用程序后禁用安全管理器。我的main() 方法的第一行:

        System.setSecurityManager(null);
        

        告诉 Tomcat 使用默认的类加载器:

        context.setLoader(new WebappLoader(getClass().getClassLoader()));
        

        现在 Tomcat 在 WebStart 中运行:-D

        【讨论】:

          【解决方案8】:

          您可以编辑您的策略文件。例如,当您部署管理员战争时,您会遇到安全问题,您必须编辑位于 tomcat conf 目录中的 catalina.policy 以获得如下所示的低条目来解决此问题。

          grant codeBase "file:${catalina.base}/webapps/admin/-" {
                          permission java.security.AllPermission;
          };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-05-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-15
            • 2014-05-15
            • 2013-12-30
            相关资源
            最近更新 更多