如果我正确理解AccessController.doPrivileged,那就是说不受信任的代码应该能够通过 所拥有的中间方法调用需要权限的方法(例如System.getProperty()
)权限。
这提出了一个问题:什么时候应该使用AccessController.doPrivileged()
?何时应该允许不受信任的代码通过中间方法调用特权代码?什么时候应该失败?
根据您的推理,请解释为何应始终允许创建ClassLoader:http://findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED
答案 0 :(得分:18)
同意Suraj's answer,但我想我会添加一个特定的例子,我需要使用特权块。
想象一下,您构建了一个为可插拔模块提供大量服务的应用程序。因此,您的应用及其服务是值得信赖的代码。但是,可插拔模块不一定是可信任的,并且被加载到它们自己的类加载器中(并且具有自己的保护域)。
当可插拔模块调用服务时,您正在实现自定义安全检查(“可插拔模块X是否有权使用此服务”)。但是服务本身可能需要一些核心Java权限(读取系统属性,写入文件等)。需要这些权限的代码包含在doPrivileged()
中,以便有效忽略来自不受信任的可插入模块的权限不足 - 仅应用受信任服务模块的权限。
答案 1 :(得分:14)
..通过具有权限的中间方法。不,最终的有效权限是域堆栈中所有权限的交集。因此,假设操作需要执行权限B,并且说某些中间LIB具有两个权限B和A.现在,当一些仅具有权限A的不受信任的代码通过LIB调用时,有效权限集为(A intersect (A+B)) = A
。因此,不受信任的代码无法利用中间LIB获得额外的权限。
什么时候应该使用? - > Java中有许多操作要求调用者域具有成功执行这些操作的某些权限。 System.getProperty是其中一个操作。所有与文件相关的操作也需要特殊权限。使用AccessController.doPrivileged调用这些操作时,将使用保护域的所有权限(权限)执行操作。因此,如果您的代码只有足够的权限,那么它就可以执行这些操作。
答案 2 :(得分:8)
本质上,AccessController.doPriviledged()等同于set-user-id文件。它说:“我特此请求使用我的权限完成此方法,即使我被没有它们的方法调用。”
答案 3 :(得分:4)
查看这些链接并向下滚动以使用doPrivileged API。
Java 6: http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html
Java 7: http://docs.oracle.com/javase/7/docs/technotes/guides/security/doprivileged.html
当最近的调用者调用AccessController checkPermission方法时,决定是否允许或拒绝所请求访问的基本算法如下:
如果调用链中任何调用者的代码没有所请求的权限,则抛出AccessControlException,除非以下条件为真 - 其代码被授予所述权限的调用者已被标记为“特权”(见下文)并且此呼叫者随后(直接或间接)呼叫的所有各方都拥有上述许可