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

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

注:依赖类:System

文章目录

1、概述

继承关系:

  • java.lang.Object
    • java.lang.SecurityManager

直接已知子类:
RMISecurityManager


public class SecurityManager extends Object

安全管理器是一个允许应用程序实现安全策略的类。它允许应用程序在执行一个可能 不安全 \color{red}{不安全} 不安全 敏感 \color{red}{敏感} 敏感的操作确定该操作是什么,以及是否是在允许执行该操作的安全上下文中执行它。应用程序可以允许或不允许该操作。

SecurityManager 包含了很多名称以 check 开头的方法。Java 库中的各种方法在执行某些潜在的敏感操作前可以调用这些方法。对 check() 的典型调用如下:

SecurityManager security = System.getSecurityManager();
if (security != null) {
    security.checkXXX(argument,  . . . );
}

因此,安全管理器通过抛出异常来提供阻止操作完成的机会。如果允许执行该操作,则安全管理器例程只是简单地返回,但如果不允许执行该操作,则抛出一个 SecurityException。该约定的惟一例外是 checkTopLevelWindow(),它返回 boolean 值。

当前的安全管理器由 System 类中的 setSecurityManager() 方法设置。当前的安全管理器由 getSecurityManager() 方法获取。

特殊方法: \color{red}{特殊方法:} 特殊方法: checkPermission(java.security.Permission pri),负责确定是应该允许还是拒绝由指定权限所指示的访问请求。默认的实现调用 :

AccessController.checkPermission(perm);

如果允许访问请求,则返回 checkPermission()。如果拒绝访问请求,则抛出 SecurityException。

从 Java 2 SDK v1.2 开始,SecurityManager 中其他所有 check()默认实现都是调用 SecurityManager checkPermission() 来确定调用线程是否具有执行所请求操作的权限。

注意: \color{red}{注意:} 注意:只带有单个权限参数的 checkPermission()总是在当前执行的线程上下文中执行安全检查。有时,应该在给定上下文中进行的安全检查实际上需要在不同 的上下文(例如,在一个辅助线程中)中进行。Java 为这种情况提供了包含有 上下文参数 上下文参数 上下文参数getSecurityContext()checkPermission()getSecurityContext()返回当前调用上下文的一个“ 快照 \color{green}{快照} 快照”(默认的实现返回一个 AccessControlContext对象)。下面是一个示例调用:

Object context = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) context = sm.getSecurityContext(); 

checkPermission(java.security.Permission pri, Object context) 使用一个上下文对象,以及根据该上下文而不是当前执行线程的上下文作出访问决策的权限。因此另一个上下文中的代码可以调用此方法,传递权限和以前保存的上下文对象。下面是一个示例调用,它使用了以前示例中获得的 SecurityManager sm

if (sm != null) sm.checkPermission(permission, context);

权限分为以下类别:文件、套接字、网络、安全性、运行时、属性、AWT、反射和可序列化。管理各种权限类别的类是 java.io.FilePermission、java.net.SocketPermission、java.net.NetPermission、java.security.SecurityPermission、java.lang.RuntimePermission、java.util.PropertyPermission、java.awt.AWTPermission、java.lang.reflect.ReflectPermission 和 java.io.SerializablePermission

除前两个(FilePermission 和 SocketPermission)类以外的所有类都是 BasicPermission 的子类,而 BasicPermission 类又是顶级权限类 Permission 的抽象子类。BasicPermission 定义了所有权限所需的功能,这些功能的名称遵从 分层属性命名惯例 \color{blue}{分层属性命名惯例} 分层属性命名惯例(例如“exitVM”、“setFactory”、“queuePrintJob”等等,也称之为“ 驼峰命名规范 \color{green}{驼峰命名规范} 驼峰命名规范”)。在名称的末尾可能出现一个“*”,前面是“.”或星号,这表示通配符匹配。例如:“a.*”、“*”是有效的,而“*a”或“a*b”是无效的。

FilePermission 和 SocketPermission 是顶级权限类 Permission 的子类。像这些命名语法比 BasicPermission 所用的语法更为复杂的类都直接是 Permission 的子类,而不是 BasicPermission 的子类。例如,对于 FilePermission 对象而言,权限名就是文件(或目录)的路径名。

某些权限类具有一个“操作”列表 某些权限类具有一个“操作”列表 某些权限类具有一个操作列表,告知允许对象所执行的操作。例如,对于 FilePermission 对象,操作列表(如“读、写”)指定了允许对指定文件(或指定目录中的文件)执行哪些操作。

其他权限类是“命名”权限 其他权限类是“命名”权限 其他权限类是命名权限,有名称但没有操作列表的类;您也许有命名的权限,也许没有。

注: \color{red}{注:} 注:还有一个暗指所有权限的 AllPermission 权限。该权限是为了简化系统管理员的工作而存在的,因为管理员可能需要执行很多需要所有(或许多)权限的任务。

有关权限相关的信息,请参阅《Permissions in the JDK》。例如,本文档包括一个列出各种 SecurityManager 的 check() 和每个方法的默认实现所需的权限表。它还包含了版本 1.2 方法所需权限和每个方法需要哪些权限的表。

有关 JDK 中对 SecurityManager 所作更改的更多信息和关于 1.1 风格安全管理器移植的建议,请参阅《security documentation》。

从以下版本开始:
JDK1.0
另请参见:
ClassLoader、SecurityException、checkTopLevelWindow()getSecurityManager()/setSecurityManager(见System类)、AccessControllerAccessControlContext、AccessControlException、Permission、BasicPermission、FilePermission、SocketPermission、PropertyPermission、RuntimePermission、AWTPermission、Policy、SecurityPermission、ProtectionDomain

2、字段摘要

2.1 protected boolean inCheck

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。(即第4.18项)

3、构造方法摘要

3.1 null

构造一个新的 SecurityManager。

public SecurityManager() {
    synchronized(SecurityManager.class) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // ask the currently installed security manager if we
            // can create a new one.
            sm.checkPermission(new RuntimePermission
                               ("createSecurityManager"));
        }
        initialized = true;
    }
}

4、方法摘要

4.1 void checkAccept(String host, int port)

如果不允许调用线程从指定的主机和端口号接受套接字连接,则抛出 SecurityException。

4.2 void checkAccess(Thread t)

如果不允许调用线程修改 thread 参数,则抛出 SecurityException。

4.3 void checkAccess(ThreadGroup g)

如果不允许调用线程修改线程组参数,则抛出 SecurityException。

4.4 void checkAwtEventQueueAccess()

已过时。 如果不允许调用线程访问 AWT 事件队列,则抛出 SecurityException。

4.5 void checkConnect(String host, int port)

如果不允许调用线程打开到指定主机和端口号的套接字连接,则抛出 SecurityException。

4.6 void checkConnect(String host, int port, Object context)

如果不允许指定的安全上下文打开与指定主机和端口号的套接字连接,则抛出 SecurityException。

4.7 void checkCreateClassLoader()

如果不允许调用线程创建新的类加载器,则抛出 SecurityException。

4.8 void checkDelete(String file)

如果不允许调用线程删除指定的文件,则抛出 SecurityException。

4.9 void checkExec(String cmd)

如果不允许调用线程创建一个子进程,则抛出 SecurityException。

4.10 void checkExit(int status)

如果不允许调用线程使用特定的状态码暂停 Java 虚拟机,则抛出 SecurityException。

4.11 void checkLink(String lib)

如果不允许调用线程动态链接由字符串参数文件指定的库代码,则抛出 SecurityException。

4.12 void checkListen(int port)

如果不允许调用线程等待与指定本地端口号进行连接的请求,则抛出 SecurityException。

4.13 void checkMemberAccess(Class<?> clazz, int which)

已过时。如果不允许调用线程访问程序,则抛出 SecurityException。

4.14 void checkMulticast(InetAddress maddr)

如果不允许调用线程使用(加入/离开/发送/接收)IP 多路广播,则抛出 SecurityException。

4.15 void checkMulticast(InetAddress maddr, byte ttl)

已过时。 由 #checkPermission(java.security.Permission) 取代

4.16 void checkPackageAccess(String pkg)

如果不允许调用线程访问由参数指定的包,则抛出 SecurityException。

public void checkPackageAccess(String pkg) {
    if (pkg == null) {
        throw new NullPointerException("package name can't be null");
    }

    String[] pkgs;
    synchronized (packageAccessLock) {
        /*
         * Do we need to update our property array?
         */
        if (!packageAccessValid) {
            String tmpPropertyStr =
                AccessController.doPrivileged(
                    new PrivilegedAction<String>() {
                        public String run() {
                            return java.security.Security.getProperty(
                                "package.access");
                        }
                    }
                );
            packageAccess = getPackages(tmpPropertyStr);
            packageAccessValid = true;
        }

        // Using a snapshot of packageAccess -- don't care if static field
        // changes afterwards; array contents won't change.
        pkgs = packageAccess;
    }

    /*
     * Traverse the list of packages, check for any matches.
     */
    for (int i = 0; i < pkgs.length; i++) {
        if (pkg.startsWith(pkgs[i]) || pkgs[i].equals(pkg + ".")) {
            checkPermission(
                new RuntimePermission("accessClassInPackage."+pkg));
            break;  // No need to continue; only need to check this once
        }
    }
}

后续解析。

4.17 void checkPackageDefinition(String pkg)

如果不允许调用线程在参数指定的包中定义类,则抛出 SecurityException。

4.18 void checkPermission(Permission perm)

如果基于当前有效的安全策略,不允许执行根据给定权限所指定的请求访问,则抛出 SecurityException。

4.19 void checkPermission(Permission perm, Object context)

如果拒绝指定的安全上下文访问由给定权限所指定的资源,则抛出 SecurityException。

public void checkPermission(Permission perm, Object context) {
    if (context instanceof AccessControlContext) {
        ((AccessControlContext)context).checkPermission(perm);
    } else {
        throw new SecurityException();
    }
}

4.20 void checkPrintJobAccess()

如果不允许调用线程发起一个打印作业请求,则抛出 SecurityException。

4.21 void checkPropertiesAccess()

如果不允许调用线程访问或修改系统属性,则抛出 SecurityException。

4.22 void checkPropertyAccess(String key)

如果不允许调用线程访问具有指定的 key 名的系统属性,则抛出 SecurityException。

4.23 void checkRead(FileDescriptor fd)

如果不允许调用线程从指定的文件描述符进行读取,则抛出 SecurityException。

4.24 void checkRead(String file)

如果不允许调用线程读取由字符串参数指定的文件,则抛出 SecurityException。

4.25 void checkRead(String file, Object context)

如果不允许指定的安全上下文读取由字符串参数所指定的文件,则抛出 SecurityException。

4.26 void checkSecurityAccess(String target)

确定是应该允许还是拒绝具有指定权限目标名的权限。

4.27 void checkSetFactory()

如果不允许调用线程设置由 ServerSocket 或 Socket 使用的套接字工厂,或者由 URL 使用的流处理程序工厂,则抛出 SecurityException。

4.28 void checkSystemClipboardAccess()

如果不允许调用线程访问系统剪贴板,则抛出 SecurityException。

4.29 boolean checkTopLevelWindow(Object window)

如果不受信任的调用线程调出由 window 参数指出的顶层窗口,则返回 false。

4.30 void checkWrite(FileDescriptor fd)

如果不允许调用线程写入指定的文件描述符,则抛出 SecurityException。

4.31 void checkWrite(String file)

如果不允许调用线程由字符串参数指定的文件,则抛出 SecurityException。

4.32 protected int classDepth(String name)

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

4.33 protected int classLoaderDepth()

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

4.34 protected ClassLoader currentClassLoader()

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

4.35 protected Class<?> currentLoadedClass()

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

4.36 protected Class[] getClassContext()

以类数组的形式返回当前执行堆栈。

4.37 boolean getInCheck()

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

4.38 Object getSecurityContext()

创建一个封装当前执行环境的对象。

4.39 ThreadGroup getThreadGroup()

调用此方法时,返回所有新创建的线程实例化后所在的线程组。

public ThreadGroup getThreadGroup() {
    return Thread.currentThread().getThreadGroup();
}

4.40 protected boolean inClass(String name)

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

4.41 protected boolean inClassLoader()

已过时。 建议不使用该类安全检查。建议使用 checkPermission() 调用。

5、方法摘要(不开放)

5.1 private static ThreadGroup getRootGroup()

返回当前正在执行的线程所属的“最高”线程组。

private static ThreadGroup getRootGroup() {
    ThreadGroup root =  Thread.currentThread().getThreadGroup();
    while (root.getParent() != null) {
        root = root.getParent();
    }
    return root;
}

5.2 private static String[] getPackages(String p)

将由已通过权限检查的包名组成的字符串转换为字符串数组并返回。

private static String[] getPackages(String p) {
    String packages[] = null;
    if (p != null && !p.equals("")) {
        java.util.StringTokenizer tok =
            new java.util.StringTokenizer(p, ",");
        int n = tok.countTokens();
        if (n > 0) {
            packages = new String[n];
            int i = 0;
            while (tok.hasMoreElements()) {
                String s = tok.nextToken().trim();
                packages[i++] = s;
            }
        }
    }

    if (packages == null)
        packages = new String[0];
    return packages;
}

后续解析。

最后

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


本文暂缓更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

进步·于辰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值