【问题标题】:SpringBoot webapp under Java SecurityManager throws exceptions when granted AllPermissionJava SecurityManager下的SpringBoot webapp在授予AllPermission时抛出异常
【发布时间】:2014-11-28 12:50:02
【问题描述】:

我们有一个 Spring Boot (1.1.6) 应用程序作为 .war 文件部署到 Tomcat 7.0.52 / OpenJDK 7 服务器。我们需要在 SecurityManager 下运行这个服务器。

即使我们使用允许对所有代码执行 AllPermission 的策略(本质上与在 SecurityManager 下运行的not相同)来操作服务器,我们也会因反射活动而引发异常。这是其中一个异常的完整堆栈跟踪。

java.lang.IllegalAccessException: Class org.apache.catalina.security.SecurityUtil$1 can not access a member of class org.springframework.boot.context.web.ErrorPageFilter with modifiers "public"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:109) ~[na:1.7.0_65]
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261) ~[na:1.7.0_65]
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253) ~[na:1.7.0_65]
    at java.lang.reflect.Method.invoke(Method.java:599) ~[na:1.7.0_65]
    at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:277) ~[catalina.jar:7.0.52]
    at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:274) ~[catalina.jar:7.0.52]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_65]
    at javax.security.auth.Subject.doAsPrivileged(Subject.java:536) ~[na:1.7.0_65]
    at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:309) ~[catalina.jar:7.0.52]
    at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:249) ~[catalina.jar:7.0.52]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237) ~[catalina.jar:7.0.52]
    at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:55) ~[catalina.jar:7.0.52]
    at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:191) ~[catalina.jar:7.0.52]
    at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:187) ~[catalina.jar:7.0.52]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:186) ~[catalina.jar:7.0.52]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) ~[catalina.jar:7.0.52]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.52]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [catalina.jar:7.0.52]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.52]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) [catalina.jar:7.0.52]
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683) [catalina.jar:7.0.52]
    at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:178) [logback-access-1.0.13.jar:na]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.52]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [catalina.jar:7.0.52]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) [tomcat-coyote.jar:7.0.52]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) [tomcat-coyote.jar:7.0.52]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) [tomcat-coyote.jar:7.0.52]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_65]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_65]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_65]

应用于服务器的策略文件如下所示:

grant { 
  permission java.security.AllPermission;
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

.. 我们添加了明确的ReflectPermission 以防AllPermission 没有包含它,但我们尝试了两种方式。

关于为什么只有当我们在具有上述策略的 SecurityManager 下运行时才会引发异常的任何指针?

【问题讨论】:

    标签: java spring tomcat spring-boot


    【解决方案1】:

    该错误不是由 Java 安全性引起的,而是由 Java 语言访问规则引起的。

    ErrorPageFilter 类是包可见的 [1]。 Tomcat 尝试通过反射调用该类的公共方法,但不能,因为根据 Java 语言规则,该类本身不可访问。

    [1]https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/java/org/springframework/boot/context/web/ErrorPageFilter.java

    (我链接的是master分支,但你实际使用的是1.1.6版本,所以上面链接的内容可能会随着时间的推移而改变)

    非公共过滤器异常。在过去,当所有过滤器都在 web.xml 中声明时,不可能使用此类非公共过滤器。我不知道 Spring Boot 内部原理,但我猜这个过滤器是使用 Servlet 3.0 API 以编程方式添加到 Web 应用程序的。

    可能的方法:

    a) 要求 Spring Boot 开发人员公开该类

    b) 更改 Apache Tomcat,以便寻找由特定接口声明的方法,而不是寻找特定类声明的方法。由 interface 声明的 java.lang.reflect.Method 可以在实现该接口的类上调用。我希望这个解决方案能够通过 sun.reflect.Reflection.ensureMemberAccess() 中的这些检查,但需要进行实际测试。

    这需要更改内部 Tomcat API 以将接口类(在本例中为 javax.servlet.Filter)作为附加参数传递给这些方法。

    从技术上讲,这需要:

    • 将问题提交到 Tomcat Bugzilla - 完成。
    • 提供一个简单的复制配方,以便对其进行测试
    • 等待下一个版本

    更新:我将此提交到 Bugzilla, https://issues.apache.org/bugzilla/show_bug.cgi?id=57281

    【讨论】:

    猜你喜欢
    • 2019-04-08
    • 2014-12-03
    • 2012-03-07
    • 2019-05-19
    • 1970-01-01
    • 2013-09-16
    • 2011-02-19
    • 2013-05-24
    • 2021-12-01
    相关资源
    最近更新 更多