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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2233761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 05:03:15  来源:igfitidea点击:

When should AccessController.doPrivileged() be used?

javasecurity

提问by Gili

If I understand AccessController.doPrivilegedcorrectly, it is saying that untrusted code should be able to invoke methods requiring permissions (such as System.getProperty()) through an intermediate method that doeshave permissions.

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

That brings up the question: when should AccessController.doPrivileged()be used? When should untrusted code be allowed to invoke privileged code through intermediate methods? When should it fail?

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

Following your reasoning, please explain why ClassLoader creation should always be allowed: http://findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED

按照您的推理,请解释为什么应始终允许创建类加载器:http: //findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED

采纳答案by Ash

Agree with Suraj's answer, but thought I'd add a specific example where I've required the use of a privileged block.

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

Imagine you've built an application that provides a number of services to pluggable modules. So your app and its services are trusted code. The pluggable modules, however, are not necessarily trusted and are loaded in their own class loaders (and have their own protection domains).

想象一下,您已经构建了一个应用程序,该应用程序为可插拔模块提供了许多服务。因此,您的应用程序及其服务是受信任的代码。然而,可插拔模块不一定是可信的,它们被加载到它们自己的类加载器中(并且有自己的保护域)。

When a pluggable module invokes a service, you are implementing custom security checks ("does pluggable module X have permission to use this service"). But the service itself might require some core Java permission (read a system property, write to a file, etc). The code that requires these permissions is wrapped in a doPrivileged()so that the insufficient permissions from the untrusted pluggable modules are effectively ignored - only the privileges of your trusted services module apply.

当可插拔模块调用服务时,您正在实施自定义安全检查(“可插拔模块 X 是否有权使用此服务”)。但服务本身可能需要一些核心 Java 权限(读取系统属性、写入文件等)。需要这些权限的代码被封装在 a 中,doPrivileged()以便有效地忽略来自不受信任的可插拔模块的不足的权限 - 只有受信任的服务模块的权限才适用。

回答by Suraj Chandran

  1. ..through an intermediate method that does have permissions. No, the final effective permissions is the intersection of all permissions in the domain stack. So suppose an operation requires a permission B to execute, and say some intermediate LIB has two permissions B and A. Now when some untrusted code with only permission A calls through LIB, the effective permission set is (A intersect (A+B)) = A. Hence the untrusted code cannot exploit intermediate LIB to gain extra permissions.

  2. When should doPriveleged be used?-> There are lot of operations in Java that require the caller domain to have certain permissions for successful execution of those operations. System.getProperty is one of those operations. All file related operations also need special permissions. When you use AccessController.doPrivileged to invoke those operations, the operation is executed with all the rights(permissions) of your protection domain. Hence if your code has enough rights only then it could execute those operations.

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

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

回答by Tim

Check out these links and scroll down to using the doPrivileged API.

查看这些链接并向下滚动以使用 doPrivileged API。

Java 6: http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html

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

Java 7:http: //docs.oracle.com/javase/7/docs/technotes/guides/security/doprivileged.html

When the AccessController checkPermission method is invoked by the most recent caller, the basic algorithm for deciding whether to allow or deny the requested access is as follows:

当最近的调用者调用 AccessController checkPermission 方法时,决定是否允许或拒绝请求的访问的基本算法如下:

If the code for any caller in the call chain does not have the requested permission, AccessControlException is thrown, unless the following is true - a caller whose code is granted the said permission has been marked as "privileged" (see below) and all parties subsequently called by this caller (directly or indirectly) all have the said permission

如果调用链中任何调用者的代码没有请求的权限,则抛出 AccessControlException ,除非以下情况为真 - 其代码被授予所述权限的调用者已被标记为“特权”(见下文)和所有各方随后由该调用者(直接或间接)调用的所有人都具有上述权限

回答by Demi

Essentially, AccessController.doPriviledged() is the equivalent of a set-user-id file. It is saying "I hereby request that this method be done with my privileges, even if I was invoked by a method that does not have them."

本质上,AccessController.doPriviledged() 相当于一个 set-user-id 文件。它是说“我在此请求以我的权限完成此方法,即使我被一个没有权限的方法调用。”