Java-API简析_java.security.AccessController类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/131212897
出自【进步*于辰的博客

1、概述

继承关系:

  • java.lang.Object
    • java.security.AccessController

public final class AccessController extends Object

AccessController 类用于与访问控制相关的操作和决定。

更确切地说,AccessController 类用于以下三个目的:

  • 基于当前生效的安全策略决定是允许还是拒绝对关键系统资源的访问,
  • 将代码标记为享有“特权”,从而影响后续访问决定,以及获取当前调用上下文的“快照”,这样即可相对于已保存的上下文作出其他上下文的访问控制决定。

checkPermission() 确定应该批准还是拒绝由指定权限所指示的访问请求。示例调用如下所示。在此例中,checkPermission() 将确定是否批准对 "/temp" 目录中名为 "testFile" 的文件的“读”访问。

FilePermission perm = new FilePermission("/temp/testFile", "read");
AccessController.checkPermission(perm);

如果允许请求的访问,则 checkPermission() 正常返回。如果拒绝,则抛出 AccessControlException。如果请求的权限类型不正确或包含无效值,则也会抛出 AccessControlException。只要可能,就给出此类信息。 假定当前线程按照调用方 1 到调用方 2 直到调用方 m 的顺序遍历了 m 个调用方。那么调用方 m 调用 checkPermission()checkPermission() 基于以下算法确定批准还是拒绝访问:

i = m;
while (i > 0) {

    if (x) {// x → caller i's domain does not have the permission)throw AccessControlException
        ...
    } else if (y) {// y → caller i is marked as privileged
        if (z)// z → a context was specified in the call to doPrivileged
            context.checkPermission(permission);
        return;
    }
    i = i - 1;
} ;

// 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() 及下文)。在做访问控制决定时,如果遇到通过调用不带上下文参数(请参见下文以获取关于上下文参数的信息)的 doPrivileged() 标记为“特权”的调用方,则 checkPermission() 将停止检查。如果该调用方的域具有指定的权限,则不进行进一步检查并且 checkPermission() 正常返回,指示允许所请求的访问。如果该域不具有指定的权限,则通常抛出异常。

“特权”功能的标准用法如下所示。如果不需要从“特权”块返回值,则使用以下代码:

   somemethod() {
        ...normal code here...
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                // privileged code goes here, for example:
                System.loadLibrary("awt");
                return null; // nothing to return
            }
        });
       ...normal code here...
  }

PrivilegedAction 是一个具有单个方法的接口,该方法名为 run() 并返回一个 Object。上述示例显示该接口的实现的创建;提供了 run() 的具体实现。调用 doPrivileged() 时,将 PrivilegedAction 实现的实例传递给它。doPrivileged() 在启用特权后从 PrivilegedAction 实现调用 run() ,并返回 run() 的返回值作为 doPrivileged() 返回值(在此示例中忽略)。

如果需要返回值,则可使用以下代码:

   somemethod() {
        ...normal code here...
        String user = (String) AccessController.doPrivileged(
          new PrivilegedAction() {
            public Object run() {
                return System.getProperty("user.name");
            }
          }
        );
        ...normal code here...
  }

如果在 run() 中执行的操作可以抛出“已检查”异常(列在方法的 throws 子句中),则需要使用 PrivilegedExceptionAction 接口代替 PrivilegedAction 接口:

   somemethod() throws FileNotFoundException {
        ...normal code here...
      try {
        FileInputStream fis = (FileInputStream) AccessController.doPrivileged(
          new PrivilegedExceptionAction() {
            public Object 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...
  }

在使用“特权”构造时务必 * 特别 * 小心,始终让享有特权的代码段尽可能小。

注意checkPermission() 始终在当前执行线程的上下文中执行安全性检查。有时,本来应该在给定上下文中进行的安全性检查实际需要在另一个 上下文 中(例如,在 worker 线程中)完成。getContext() 和 AccessControlContext 类是针对这种情况提供的。getContext() 获取当前调用上下文的“快照”,并将其置于它所返回的 AccessControlContext 对象中。示例调用如下:

AccessControlContext acc = AccessController.getContext()

AccessControlContext 本身具有一个 checkPermission() ,该方法基于它所封装的上下文而不是当前执行线程作出访问决定。因此,另一上下文中的代码可以在以前保存的 AccessControlContext 对象上调用该方法。示例调用如下:

acc.checkPermission(permission)

有时候您还可能不知道用于检查上下文的权限的优先级。这时可以使用 doPrivileged() 来获取上下文:

somemethod() {
      AccessController.doPrivileged(new PrivilegedAction() {
           public Object run() {
              // Code goes here. Any permission checks within this
              // run method will require that the intersection of the
              // callers protection domain and the snapshot's
              // context have the desired permission.
           }
      }, acc);
      ...normal code here...
}

另请参见:
AccessControlContext

2、方法摘要

2.1 static void checkPermission(Permission perm)

基于当前生效的安全策略确定是否允许指定权限所指示的访问请求。

2.2 static <T> T doPrivileged(PrivilegedAction<T> action)

启用特权,执行指定的 PrivilegedAction。

2.3 static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context)

通过指定的 AccessControlContext 启用和限制特权,执行指定的 PrivilegedAction。

2.4 static <T> T doPrivileged(PrivilegedExceptionAction<T> action)

启用特权,执行指定的 PrivilegedExceptionAction。

2.5 static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context)

通过指定的 AccessControlContext 启用和限制特权,执行指定的 PrivilegedExceptionAction。

2.6 static AccessControlContext getContext()

此方法获取当前调用上下文(包括当前 Thread 的继承 AccessControlContext)的“快照”,并将其置于 AccessControlContext 对象中。

最后

如果大家需要Java-API文档,我上传了《Java-API文档-包含5/8/11三个版本》。


本文暂缓更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进步·于辰

谢谢打赏!!很高兴可以帮到你!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值