使用https-URLS设置哪个权限以避免安全管理器出错?

时间:2015-09-18 07:56:55

标签: java securitymanager javapolicy

在针对客户的软件中,我们必须阅读给定的URL来解析其内容。客户还需要激活Tomcat-Security-Manager,让Java-Policies控制程序的功能。

现在,通过读取URL,发生异常“javax.net.ssl.SSLKeyException:RSA premaster secret error”,但仅在某些条件下:

  • 如果网址是HTTPS但不是HTTP
  • 如果安全管理器已激活,则不会在其停用时或 如果在全局grant-Block中设置了AllPermission
  • 仅使用Java 6,而不是Java 7(客户当前需要Java 6)
  • 仅限Tomcat6,而不是Tomcat 7(客户目前需要Tomcat 6)

安全违规发生在Java代码的某处,限制在我们的代码库中的AllPermission不会阻止错误。

那么,是否有人有想法,为Java 6设置哪个权限,以便它可以处理HTTPS?

其他信息:它在一个tomcat中运行,在带有OpenJDK的Debian-Linux上运行。

编辑:我在变量JAVA_OPTS中向Tomcats / etc / default / tomcat6添加了Java-Param“-Djava.security.debug = access,failure”。但在日志中我没有其他消息。代码可能会在触发它们之前询问权限吗?

EDIT2:我找到了正确的位置并获得了完整的堆栈跟踪(删除了特定的客户部分):

new URL(params.url).text

EDIT3:到目前为止,我假设使用Java类URL来访问资源的内容。但这是不真实的。它使用Grails-Code将Groovy-URL-object与getText()方法一起使用:

function showdivs() { //this is called, when you click a link
        var divs = $("#info,#add_new");

        //Show chosen div, and hide all others
        $("li a").click(function() {// here the clickhandler is added, so the first time it won't work

            $(divs).hide();
            $("#" + $(this).attr("class")).show();

        });

错误发生在这一行。这是Grails-version 2.2.4。

2 个答案:

答案 0 :(得分:8)

发现所有必需权限的简便方法是使用参数

运行
-Djava.security.debug=access,failure

然后,您将获得有关每个失败的安全访问,有效保护域等的完整信息。

答案 1 :(得分:8)

解决方案之后的几条评论和OP确认决议(摘要)

根本原因是在多个位置存在sunjce_provider.jar。这被OP发现后被认为是许多可能的根本原因之一(参见本答案的最后部分和评论记录)。根据OP的评论:

  

我在多个目录中有sunjce_provider.jar。我试图给Java 6的所有三个位置提供权限,虽然显然只有一个是JAVA_HOME - 并且它有效。不知何故使用了其他位置之一,尽管它不在java.ext.dirs-property

因此,本案的解决方案是确保应用有权访问sunjce_provider.jar的正确副本

我已经从我原来的答案中留下了主要观点以及有助于诊断的评论,以供稍后发现的人使用

导致解决方案的原始答案和评论

  1. http不会发生这种情况,因为您的网络应用(即此连接的客户端,即使它在tomcat中运行),也不需要在此生成密钥配置。

  2. 事实上它只在启用SecurityManager时发生,但如果禁用或全局AllPermission则表明其文件权限错误。它表明密钥长度不是问题(例如mentioned here

  3. 其他similar报告on web表示可能的根本原因是缺少jar(通常引用sunjce_provider.jar)。堆栈跟踪确认根本原因异常是NoSuchAlgorithmException KeyGenerator正在寻找算法SunTlsRsaPremasterSecret并且无法找到它。在您的情况下,因为这只发生在特定的SecurityManager配置中,它可能是 无法访问的 jar(由于安全权限)。

    我的猜测是你没有对包含RSA keygen算法所需jar的正确目录启用grant codeBase权限。我建议的做法是通过您的webapp和JRE目录结构来查找保留运行时jar的位置,并确保它们在grant中具有catalina.policy个权限。

    在默认配置中 - 例如 - 你应该看到某个地方

    // These permissions apply to all shared system extensions
    grant codeBase "file:${java.home}/jre/lib/ext/-" {
            permission java.security.AllPermission;
    };
    

    有关详细信息,请参阅tomcat安全管理器的this section"如何"。您需要检查一些事项 - 确保${java.home}/jre/lib/ext/是运行时罐子的位置。如果不是 - 改变指向正确位置的路径( ,它们位于我的OpenJDK 6版本 - 构建27)。特别要在那里看到sunjce_provider.jarsunpkcs11.jar。确保您的政策文件中存在上述部分。

    可能是代码依赖于您的webapp中的一些jar - 例如在${catalina.base}/path/to/your/webapp/WEB-INF/classes/中 - 在这种情况下,您需要授予该目录的权限。

    导致相同或类似症状的其他问题

    1. 无法找到或访问sunpkcs11.jar的应用会提供相同的错误消息(在Ubuntu + openjdk6 + tomcat6系统上验证)。这个罐子的副本很可能也会出现。

    2. 检查/etc/java-6-openjdk/security/java.security。它应该列出那里的提供者 - 检查那里有一条类似security.provider.n = sun.security.pkcs11.SunPKCS11的行 - 如果缺少该行,你也会得到这个错误(在同一系统上验证)

    3. Debian bug report讨论了在SecurityManager

    4. 下运行时罐子位置的问题

      调试评论

      根据其他答案,您可以尝试在catalina.sh中将-Djava.security.debug=access,failure添加到CATALINA_OPTSJAVA_OPTS以启用调试 - 默认情况下应记录到catalina.out (或者您在catalina.sh中通过CATALINA_OUT设置日志记录的位置。您应该看到SecurityManager的输出。

      你也可以试试-Djava.security.debug=all. You will get a huge catalina.out`,但你可以找一些可能有帮助的词(比如"失败" !!!)

      遵循堆栈跟踪中的代码

      您的异常被抛出here。看看如何抛出异常 - this method必须返回null。它swallows Exceptions - 这并不好,并且很难准确诊断该代码的哪个部分失败。我的钱将在this line - canUseProvider()可能会返回false。这一切都指向提供者jar由于某种原因无法访问。

      我假设您在输出中没有看到任何访问冲突,即使使用-Djava.security.debug=access,failure也是如此。您可以尝试-Djava.security.debug=all,尽管这可能只会产生更多不相关的日志记录。如果没有访问冲突, 可能 在您的类路径上以某种方式具有该jar的两个版本,并且运行时正在访问(或尝试访问错误的jar)。此Q/A中描述了与此类似的案例。