什么时候应该使用AccessController.doPrivileged()?

Gil*_*ili 35 java security

如果我理解AccessController.doPrivileged正确,它是说,不可信代码应能够调用要求的权限(例如,方法System.getProperty())通过一个中间方法确实有权限.

这提出了一个问题:什么时候应该AccessController.doPrivileged()使用?何时应该允许不受信任的代码通过中间方法调用特权代码?什么时候失败?

根据您的推理,请解释为什么应始终允许创建ClassLoader:http://findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED

Ash*_*Ash 18

同意Suraj的回答,但我想我会添加一个特定的例子,我需要使用特权块.

想象一下,您构建了一个为可插拔模块提供大量服务的应用程序.因此,您的应用及其服务是值得信赖的代码.但是,可插拔模块不一定是可信任的,并且被加载到它们自己的类加载器中(并且具有它们自己的保护域).

当可插拔模块调用服务时,您正在实现自定义安全检查("可插拔模块X是否有权使用此服务").但是服务本身可能需要一些核心Java权限(读取系统属性,写入文件等).需要这些权限的代码包含在一个中,doPrivileged()以便有效忽略来自不受信任的可插入模块的不足权限 - 仅应用受信任服务模块的权限.

  • @Ash,给定A有权调用X但B没有,A调用B调用X.DoPrivileged()是否意味着"B没有权限调用X,但我确实和我保证."所以A现在可以调用X"? (2认同)

Sur*_*ran 14

  1. ..通过具有权限的中间方法.不,最终的有效权限是域堆栈中所有权限的交集.因此假设一个操作需要一个权限B来执行,并说一些中间LIB有两个权限B和A.现在当一些只有权限A的不可信代码通过LIB调用时,有效权限集是(A intersect (A+B)) = A.因此,不受信任的代码无法利用中间LIB来获得额外的权限.

  2. 应该什么时候使用? - > Java中有许多操作要求调用者域具有成功执行这些操作的某些权限.System.getProperty是其中一个操作.所有与文件相关的操作也需要特殊权限.使用AccessController.doPrivileged调用这些操作时,将使用保护域的所有权限(权限)执行操作.因此,如果您的代码只有足够的权限,那么它可以执行这些操作.

  • 我同意,如果A调用B,则需要特权块才能采用B的权限.但是如果B然后调用C(即使是在特权块内),如果C的上下文没有所需的权限,它会不会失败?它是否仍然开始再次从权限"堆栈"调用?(我暂时没有在这方面做任何事情来测试它 - 只需要处理AccessController文档). (3认同)
  • @Suraj,我已经重新审视了这个问题,我认为你的第一点是错误的。我的理解如下:`A` 无权访问磁盘上的文件,但允许 `A` 构造一个 `Font`,即使它在后台访问磁盘上的文件。`Font` 类将它的文件访问封装在一个 `doPrivileged()` 块中,本质上是说“即使我的调用者没有权限,相信我也会调用特权代码。我保证我不会让他做任何他不应该做的事情” . 你同意? (2认同)

Dem*_*emi 9

实质上,AccessController.doPriviledged()相当于set-user-id文件.它说:"我特此请求使用我的权限完成此方法,即使我被没有它们的方法调用."