java SecurityManager拒绝在某些系统上明确允许的权限

java SecurityManager拒绝在某些系统上明确允许的权限,java,permissions,wildfly-10,java-security-manager,Java,Permissions,Wildfly 10,Java Security Manager,我正在一台WildFly 10.1.0-Final应用服务器上运行一个带有Drools的应用程序。由于Drools执行的代码不受信任,我决定构建一个自定义沙箱,以允许安全执行 因为没有外部模块可以添加到应用服务器,所以我决定,为了有效地使用这个沙箱,我必须创建一个合适的环境 因此,在服务器的standalone.xml中,我为所有战争定义了最大权限集和最小权限集,我将其设置为java.permission.AllPermission,从而通常允许执行所有代码 然后,我向服务器添加了-secmgr

我正在一台
WildFly 10.1.0-Final
应用服务器上运行一个带有
Drools
的应用程序。由于Drools执行的代码不受信任,我决定构建一个自定义沙箱,以允许安全执行

因为没有外部模块可以添加到应用服务器,所以我决定,为了有效地使用这个沙箱,我必须创建一个合适的环境

因此,在服务器的
standalone.xml
中,我为所有战争定义了
最大权限集
最小权限集
,我将其设置为
java.permission.AllPermission
,从而通常允许执行所有代码

然后,我向服务器添加了
-secmgr
标志,以激活SecurityManager。我能够按预期使用该应用程序,并且多次调用
AccessController.doPrivileged()
确实检查了权限并允许所需的操作

然后,我创建了一个服务类,它将创建一个沙盒上下文来检查访问

它显式创建一个
AccessControlContext
,其中
CodeBase
null
(表示所有代码)和
ProtectionDomain
,具有Drools-
运行时.getClassLoader
运行时.accessDeclaredMembers
Reflect.suppressAccessChecks
的三个必要权限。然后,我使用所需的调用(
StatefulKnowledgeSession.fireAllRules
)和沙盒上下文调用
AccessController.doPrivileged

在我的开发系统上,当drools规则尝试执行任何不允许的操作(例如,创建文件)时,会抛出一个
ConsequenceException
,原因是
AccessControlException
拒绝访问
文件。write

在我们的生产系统上,使用了相同的配置和部署,但是由于
AccessControlException
声明不允许
Runtime.getClassLoader
而导致所有调用失败

我调试了实时系统,当调用
sandboxContext.checkPermission(newruntimepermission(“getClassLoader”))
时,没有抛出异常,这告诉我上下文本身允许它

然而,我们的生产机器拒绝了许可

系统的唯一区别是操作系统版本,因为我使用的是
Ubuntu
机器,而生产服务器是
CentOS
机器

更新

调试服务器时发现,另一个
ProtectionDomain
未签名且没有代码库,并且缺少
Runtime.getClassLoader
权限。然而,这个特定的
ProtectionDomain
并没有出现在我的开发机器上,我无法找到它的来源

更新2

更多信息: 抛出异常时,AccessControlStack包含一个特权上下文(我实例化并期望的上下文)和5个额外的
ProtectionDomain
s。其中一个(违规者)如前所述,拥有
(null)
CodeSource
,没有主体,拥有
null
PermissionCollection,并使用
org.drools.util.CompositeClassLoader

此域授予的权限(取自
Domain.toString()
):

这显然没有运行时.getClassLoader,但是,根据我阅读的文档,因为我通过
doPrivileged
授予该权限,这根本不重要

我看到ApplicationServer使用Wildfly Elytron 1.0.2.Final作为其SecurityManager-Elytron是否可能不实现此行为

更新3:

使用第三台开发人员机器进行检查,但该机器也出现故障。由于这台机器也使用Ubuntu,我们可以有把握地说,
CentOS
不是原因

更新4:

正如您所见,所授予的权限与默认的
java.policy
权限大致相同,根据Wildfly Docs的说法,这些权限甚至不应该再被使用


我们发现,
org.jboss.security.jacc.DelegatingPolicy
似乎将权限委托给了
java.policy
中定义的权限,而不是
standalone.xml

doPrivileged
不能用来提升未来调用方的权限,只能提升过去调用方的权限。备选方案:在服务器端自主地打包库,并使用任何特定于WildFly的配置向该JAR的域授予必要的权限。但是:a)lib可能需要具有安全意识,即在必要时使用
doPrivileged
本身。b) 如果AS使用的
SecurityManager
不会无条件地将权限检查委托给线程的ACC(这似乎是
WildFlySecurityManager
的情况),那么lib可能会被迫使用其专有等价物
doPrivileged
。旁注:
运行时权限(“accessDeclaredMembers”)
ReflectPermission(“suppressAccessChecks”)
至少在标准
SecurityManager
下被视为破坏沙箱的权限。在授予它们之前请三思。感谢您的这些见解,它们确实有助于理解整个安全体系结构。顺便说一句,我不认为我可以删除它们,因为drools需要它们,但我认为这只是类加载器。你知道如何将这些显式地授予类加载器,而不允许其他人使用吗?我不知道Drools是什么以及它是如何工作的。起初,我理解您的目标是对Drools本身进行沙箱处理,而您明确表示您的目标是对Drools执行的代码进行沙箱处理。我真傻。忽略我的评论,我建议重新流口水
("java.net.SocketPermission" "localhost:0" "listen,resolve")
("java.net.SocketPermission" "localhost:0" "listen,resolve")
("javax.security.jacc.WebResourcePermission" "/")
("java.util.PropertyPermission" "java.specification.version" "read")
("java.util.PropertyPermission" "java.version" "read")
("java.util.PropertyPermission" "os.arch" "read")
("java.util.PropertyPermission" "java.specification.vendor" "read")
("java.util.PropertyPermission" "java.vm.specification.name" "read")
("java.util.PropertyPermission" "java.vm.vendor" "read")
("java.util.PropertyPermission" "path.separator" "read")
("java.util.PropertyPermission" "os.version" "read")
("java.util.PropertyPermission" "file.separator" "read")
("java.util.PropertyPermission" "line.separator" "read")
("java.util.PropertyPermission" "java.vm.specification.vendor" "read")
("java.util.PropertyPermission" "java.specification.name" "read")
("java.util.PropertyPermission" "java.vendor.url" "read")
("java.util.PropertyPermission" "java.vendor" "read")
("java.util.PropertyPermission" "java.vm.version" "read")
("java.util.PropertyPermission" "java.vm.name" "read")
("java.util.PropertyPermission" "java.vm.specification.version" "read")
("java.util.PropertyPermission" "os.name" "read")
("java.util.PropertyPermission" "java.class.version" "read")
("java.lang.RuntimePermission" "stopThread")
("javax.security.jacc.WebRoleRefPermission" "" "**")
("javax.security.jacc.WebRoleRefPermission" "Faces Servlet" "**")
("javax.security.jacc.WebRoleRefPermission" "metaform" "**")
("javax.security.jacc.WebUserDataPermission" "/")