AccessController 类用于访问控制操作和决策。
更具体地说,AccessController 类用于三个目的:
- 根据当前有效的安全策略,决定是允许还是拒绝对关键系统资源的访问,
- 将代码标记为“特权”,从而影响后续的访问确定,以及
- 获取当前调用上下文的“快照”,以便可以根据保存的上下文做出来自不同上下文的访问控制决策。
checkPermission 方法确定是否应授予或拒绝指定权限指示的访问请求。下面显示了一个示例调用。在此示例中,checkPermission 将确定是否授予对“/temp”目录中名为“testFile”的文件的“读取”访问权限。
FilePermission perm = new FilePermission("/temp/testFile", "read");
AccessController.checkPermission(perm);
如果请求的访问被允许,checkPermission 会安静地返回。如果被拒绝,则抛出 AccessControlException。如果请求的权限类型不正确或包含无效值,也会抛出 AccessControlException。此类信息会尽可能提供。假设当前线程遍历m个调用者,顺序为调用者1到调用者2再到调用者m。然后调用者 m 调用了 checkPermission 方法。 checkPermission 方法根据以下算法确定是授予还是拒绝访问:
for (int i = m; i > 0; i--) {
if (caller i's domain does not have the permission)
throw AccessControlException
else if (caller i is marked as privileged) {
if (a context was specified in the call to doPrivileged)
context.checkPermission(permission)
if (limited permissions were specified in the call to doPrivileged) {
for (each limited permission) {
if (the limited permission implies the requested permission)
return;
}
} else
return;
}
}
// Next, check the context inherited when the thread was created.
// Whenever a new thread is created, the AccessControlContext at
// that time is stored and associated with the new thread, as the
// "inherited" context.
inheritedContext.checkPermission(permission);
调用者可以被标记为“特权”(参见 doPrivileged 及下文)。在做出访问控制决策时,checkPermission 方法会停止检查它是否到达了通过不带上下文参数的 doPrivileged 调用标记为“特权”的调用方(有关上下文参数的信息,请参见下文)。如果该调用者的域具有指定的权限并且至少一个限制权限参数(如果有的话)暗示请求的权限,则不会进行进一步检查并且 checkPermission 安静地返回,表明允许请求的访问。如果该域没有指定的权限,则会像往常一样抛出异常。如果调用者的域具有指定的权限,但在对 doPrivileged 的调用中给出的任何限制权限参数并未暗示它,则权限检查将继续,直到没有更多的调用者或另一个 doPrivileged 调用匹配请求的权限并正常返回。
“特权”功能的正常使用如下。如果您不需要从“特权”块中返回值,请执行以下操作:
somemethod() {
...normal code here...
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
// privileged code goes here, for example:
System.loadLibrary("awt");
return null; // nothing to return
}
});
...normal code here...
}
PrivilegedAction 是一个只有一个方法的接口,名为 run 。上面的示例显示了该接口的实现的创建;提供了 run 方法的具体实现。当调用 doPrivileged 时,一个 PrivilegedAction 实现的实例被传递给它。 doPrivileged方法在启用权限后从PrivilegedAction实现调用run方法,并将run方法的返回值作为doPrivileged返回值返回(在本例中被忽略)。
如果你需要返回一个值,你可以做类似下面的事情:
somemethod() {
...normal code here...
String user = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return System.getProperty("user.name");
}
});
...normal code here...
}
如果在您的 run 方法中执行的操作可能引发“已检查”异常(在方法的 throws 子句中列出的异常),那么您需要使用 PrivilegedExceptionAction 接口而不是 PrivilegedAction 接口:
somemethod() throws FileNotFoundException {
...normal code here...
try {
FileInputStream fis = AccessController.doPrivileged(
new PrivilegedExceptionAction<FileInputStream>() {
public FileInputStream run() throws FileNotFoundException {
return new FileInputStream("someFile");
}
});
} catch (PrivilegedActionException e) {
// e.getException() should be an instance of FileNotFoundException,
// as only "checked" exceptions will be "wrapped" in a
// PrivilegedActionException.
throw (FileNotFoundException) e.getException();
}
...normal code here...
}
在使用“特权”结构时*非常*小心,并始终记住使特权代码部分尽可能小。您可以传递 Permission 参数以进一步限制“特权”的范围(见下文)。
请注意,checkPermission 始终在当前执行线程的上下文中执行安全检查。有时,应该在给定上下文中进行的安全检查实际上需要在不同的上下文(例如,来自工作线程内)。针对这种情况提供了getContext 方法和AccessControlContext类。 getContext 方法获取当前调用上下文的“快照”,并将其放置在它返回的 AccessControlContext 对象中。示例调用如下:
AccessControlContext acc = AccessController.getContext()
AccessControlContext 本身有一个 checkPermission 方法,可以根据上下文做出访问决策它封装,而不是当前执行线程的封装。因此,不同上下文中的代码可以在先前保存的 AccessControlContext 对象上调用该方法。示例调用如下:
acc.checkPermission(permission)
也有一些时候您事先不知道检查上下文的权限。在这些情况下,您可以使用带上下文的 doPrivileged 方法。您还可以通过传递额外的 Permission 参数来限制特权代码的范围。
somemethod() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
// Code goes here. Any permission checks within this
// run method will require that the intersection of the
// caller's protection domain and the snapshot's
// context have the desired permission. If a requested
// permission is not implied by the limiting FilePermission
// argument then checking of the thread continues beyond the
// caller of doPrivileged.
}
}, acc, new FilePermission("/temp/*", read));
...normal code here...
}
传递 AllPermission 实例的限制 Permission 参数相当于调用等效的 doPrivileged 方法而不限制 Permission 参数。传递 Permission 的零长度数组会禁用代码权限,以便检查始终在该 doPrivileged 方法的调用者之外继续进行。
- 自从:
- 1.2
- 参见:
-
方法总结
修饰符和类型方法描述static voidcheckPermission(Permission perm) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。根据当前的AccessControlContext和安全策略,确定是否应允许或拒绝由指定权限指示的访问请求。static <T> TdoPrivileged(PrivilegedAction<T> action) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedAction。static <T> TdoPrivileged(PrivilegedAction<T> action, AccessControlContext context) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限执行指定的PrivilegedAction。static <T> TdoPrivileged(PrivilegedAction<T> action, AccessControlContext context, Permission... perms) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedAction。static <T> TdoPrivileged(PrivilegedExceptionAction<T> action) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedExceptionAction。static <T> TdoPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限执行指定的PrivilegedExceptionAction。static <T> TdoPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedExceptionAction。static <T> TdoPrivilegedWithCombiner(PrivilegedAction<T> action) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedAction。static <T> TdoPrivilegedWithCombiner(PrivilegedAction<T> action, AccessControlContext context, Permission... perms) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedAction。static <T> T已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedExceptionAction。static <T> TdoPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedExceptionAction。static AccessControlContext已弃用,将被删除:此 API 元素可能会在未来版本中删除。此方法获取当前调用上下文的“快照”,其中包括当前线程继承的AccessControlContext和任何有限的权限范围,并将其放置在AccessControlContext对象中。
-
方法详情
-
doPrivileged
已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedAction。该动作是用all调用者保护域所拥有的权限。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。请注意,在执行操作时,与当前
AccessControlContext关联的任何DomainCombiner都将被忽略。- 类型参数:
T- PrivilegedAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。- 返回:
-
操作的
run方法返回的值。 - 抛出:
NullPointerException- 如果操作是null- 参见:
-
doPrivilegedWithCombiner
已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedAction。该动作是用all调用者保护域所拥有的权限。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。此方法在执行操作时保留当前 AccessControlContext 的
DomainCombiner(可能为空)。- 类型参数:
T- PrivilegedAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。- 返回:
-
操作的
run方法返回的值。 - 抛出:
NullPointerException- 如果操作是null- 自从:
- 1.6
- 参见:
-
doPrivileged
已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限执行指定的PrivilegedAction。该操作是使用调用者的保护域所拥有的权限与指定的AccessControlContext所代表的域所拥有的权限的交集来执行的。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。如果安装了安全管理器并且指定的
AccessControlContext不是由系统代码创建的,并且调用者的ProtectionDomain没有被授予“createAccessControlContext”SecurityPermission,那么该操作将在没有权限的情况下执行。- 类型参数:
T- PrivilegedAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。context- 一个访问控制上下文表示在执行指定操作之前应用于调用方域权限的限制。如果上下文是null,则不应用额外的限制。- 返回:
-
操作的
run方法返回的值。 - 抛出:
NullPointerException- 如果操作是null- 参见:
-
doPrivileged
public static <T> T doPrivileged(PrivilegedAction <T> action, AccessControlContext context, Permission ... perms) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedAction。该操作是使用调用者的保护域所拥有的权限与指定的AccessControlContext所代表的域所拥有的权限的交集来执行的。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。如果安装了安全管理器并且指定的
AccessControlContext不是由系统代码创建的,并且调用者的ProtectionDomain没有被授予“createAccessControlContext”SecurityPermission,那么该操作将在没有权限的情况下执行。- 类型参数:
T- PrivilegedAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。context- 一个访问控制上下文表示在执行指定操作之前应用于调用方域权限的限制。如果上下文是null,则不应用额外的限制。perms-Permission参数限制调用者权限的范围。参数的数量是可变的。- 返回:
-
操作的
run方法返回的值。 - 抛出:
NullPointerException- 如果 action 或 perms 或 perms 的任何元素是null- 自从:
- 1.8
- 参见:
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedAction <T> action, AccessControlContext context, Permission ... perms) 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedAction。该操作是使用调用者的保护域所拥有的权限与指定的AccessControlContext所代表的域所拥有的权限的交集来执行的。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。此方法在执行操作时保留当前 AccessControlContext 的
DomainCombiner(可能为空)。如果安装了安全管理器并且指定的
AccessControlContext不是由系统代码创建的,并且调用者的ProtectionDomain没有被授予“createAccessControlContext”SecurityPermission,那么该操作将在没有权限的情况下执行。- 类型参数:
T- PrivilegedAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。context- 一个访问控制上下文表示在执行指定操作之前应用于调用方域权限的限制。如果上下文是null,则不应用额外的限制。perms-Permission参数限制调用者权限的范围。参数的数量是可变的。- 返回:
-
操作的
run方法返回的值。 - 抛出:
NullPointerException- 如果 action 或 perms 或 perms 的任何元素是null- 自从:
- 1.8
- 参见:
-
doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction <T> action) throws PrivilegedActionException 已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedExceptionAction。该动作是用all调用者保护域所拥有的权限。如果操作的
run方法抛出一个未经检查异常,它将通过此方法传播。请注意,在执行操作时,与当前
AccessControlContext关联的任何DomainCombiner都将被忽略。- 类型参数:
T- PrivilegedExceptionAction 的run方法返回值的类型。- 参数:
action- 要执行的操作- 返回:
-
操作的
run方法返回的值 - 抛出:
PrivilegedActionException- 如果指定操作的run方法抛出一个检查异常NullPointerException- 如果操作是null- 参见:
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction <T> action) throws PrivilegedActionException 已弃用,将被删除:此 API 元素可能会在未来版本中删除。在启用权限的情况下执行指定的PrivilegedExceptionAction。该动作是用all调用者保护域所拥有的权限。如果操作的
run方法抛出一个未经检查异常,它将通过此方法传播。此方法在执行操作时保留当前 AccessControlContext 的
DomainCombiner(可能为空)。- 类型参数:
T- PrivilegedExceptionAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。- 返回:
-
操作的
run方法返回的值 - 抛出:
PrivilegedActionException- 如果指定操作的run方法抛出一个检查异常NullPointerException- 如果操作是null- 自从:
- 1.6
- 参见:
-
doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction <T> action, AccessControlContext context) throws PrivilegedActionException 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限执行指定的PrivilegedExceptionAction。该操作是使用调用者的保护域所拥有的权限与指定的AccessControlContext所代表的域所拥有的权限的交集来执行的。如果操作的
run方法抛出一个未经检查异常,它将通过此方法传播。如果安装了安全管理器并且指定的
AccessControlContext不是由系统代码创建的,并且调用者的ProtectionDomain没有被授予“createAccessControlContext”SecurityPermission,那么该操作将在没有权限的情况下执行。- 类型参数:
T- PrivilegedExceptionAction 的run方法返回值的类型。- 参数:
action- 要执行的操作context- 一个访问控制上下文表示在执行指定操作之前应用于调用方域权限的限制。如果上下文是null,则不应用额外的限制。- 返回:
-
操作的
run方法返回的值 - 抛出:
PrivilegedActionException- 如果指定操作的run方法抛出一个检查异常NullPointerException- 如果操作是null- 参见:
-
doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction <T> action, AccessControlContext context, Permission ... perms) throws PrivilegedActionException 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedExceptionAction。该操作是使用调用者的保护域所拥有的权限与指定的AccessControlContext所代表的域所拥有的权限的交集来执行的。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。如果安装了安全管理器并且指定的
AccessControlContext不是由系统代码创建的,并且调用者的ProtectionDomain没有被授予“createAccessControlContext”SecurityPermission,那么该操作将在没有权限的情况下执行。- 类型参数:
T- PrivilegedExceptionAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。context- 一个访问控制上下文表示在执行指定操作之前应用于调用方域权限的限制。如果上下文是null,则不应用额外的限制。perms-Permission参数限制调用者权限的范围。参数的数量是可变的。- 返回:
-
操作的
run方法返回的值。 - 抛出:
PrivilegedActionException- 如果指定操作的run方法抛出一个检查异常NullPointerException- 如果 action 或 perms 或 perms 的任何元素是null- 自从:
- 1.8
- 参见:
-
doPrivilegedWithCombiner
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction <T> action, AccessControlContext context, Permission ... perms) throws PrivilegedActionException 已弃用,将被删除:此 API 元素可能会在未来版本中删除。使用指定的AccessControlContext启用和限制的权限以及指定的Permission参数限制的权限范围执行指定的PrivilegedExceptionAction。该操作是使用调用者的保护域所拥有的权限与指定的AccessControlContext所代表的域所拥有的权限的交集来执行的。如果操作的
run方法抛出(未经检查的)异常,它将通过此方法传播。此方法在执行操作时保留当前 AccessControlContext 的
DomainCombiner(可能为空)。如果安装了安全管理器并且指定的
AccessControlContext不是由系统代码创建的,并且调用者的ProtectionDomain没有被授予“createAccessControlContext”SecurityPermission,那么该操作将在没有权限的情况下执行。- 类型参数:
T- PrivilegedExceptionAction 的run方法返回值的类型。- 参数:
action- 要执行的操作。context- 一个访问控制上下文表示在执行指定操作之前应用于调用方域权限的限制。如果上下文是null,则不应用额外的限制。perms-Permission参数限制调用者权限的范围。参数的数量是可变的。- 返回:
-
操作的
run方法返回的值。 - 抛出:
PrivilegedActionException- 如果指定操作的run方法抛出一个检查异常NullPointerException- 如果 action 或 perms 或 perms 的任何元素是null- 自从:
- 1.8
- 参见:
-
getContext
已弃用,将被删除:此 API 元素可能会在未来版本中删除。此方法获取当前调用上下文的“快照”,其中包括当前线程继承的AccessControlContext和任何有限的权限范围,并将其放置在AccessControlContext对象中。然后可以在稍后的时间点检查此上下文,可能在另一个线程中。- 返回:
AccessControlContext基于当前上下文。- 参见:
-
checkPermission
已弃用,将被删除:此 API 元素可能会在未来版本中删除。根据当前的AccessControlContext和安全策略,确定是否应允许或拒绝由指定权限指示的访问请求。如果允许访问请求,此方法会安静地返回,否则会抛出AccessControlException。AccessControlException的getPermission方法返回Permission对象实例 (perm}。- 参数:
perm- 请求的权限。- 抛出:
AccessControlException- 如果根据当前的安全策略不允许指定的权限。NullPointerException- 如果指定权限为null并根据当前有效的安全策略进行检查。
-