欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JDK源码分析——SecurityManager安全管理器实例分析

程序员文章站 2022-05-12 11:32:55
...

目录


1 样例github

https://github.com/mh47838704/JavaExample

参考文章:http://47777205.com/view/24


2 安全管理器简介

* The security manager is a class that allows
* applications to implement a security policy. It allows an
* application to determine, before performing a possibly unsafe or
* sensitive operation, what the operation is and whether
* it is being attempted in a security context that allows the
* operation to be performed. The
* application can allow or disallow the operation

上面是摘自安全管理器的介绍:Java安全管理器允许应用程序设置一个安全管理策略,通过安全管理策略实现对应用程序中的敏感的操作的管理(运行或者是禁制)

2.1 获取系统管理器

在Java中应用程序启动的时候是默认没有设置安全管理器的,可以通过下面的代码观察,下面的代码在常规的启动的时候会输出null:

System.out.println("系统当前的安全管理器:"+System.getSecurityManager());

2.2 设置系统管理器

在Java中可以通过配置启用jdk中默认的安全管理器,然后再使用上面的代码调试,那么会显示相应的实例,而不是null


VM options: -Djava.security.manager

2.3 JDK默认安全策略文件

在最前面说到了可以配置策略,那么策略到底是一个什么样的文件呢?既然在java中有默认的安全管理器,那么是不是也意味着有默认的策略配置文件呢?当然有,后面会对文件中的内容进行解释:

JDK\jre\lib\security\java.policy

2.4 自定义安全策略文件

问题又来了,当默认的策略不能满足我们的需求的时候怎么办呢?当然是自定义策略配置文件了,格式参考java.policy即可。那么如何使得我们的默认安全管理器加载呢?,使用如下启动命令参数即可(注意:一个等号“=”代表自定义策略文件和默认策略文件java.policy共同生效,两个等号“==”表示只有自定义策略文件生效

VM options:-Djava.security.policy="...\JavaExample\src\test\resources\conf\sjava.policy"

自定义策略内容格式:

grant {
    // 注解下面的权限配置会引起文件读取错误和配置信息读取错误
    permission java.util.PropertyPermission "file.encoding", "read";
    permission java.io.FilePermission "C:\\Users\\Administrator\\Desktop\\fileTest.txt", "read";
};

3 样例分析

3.1 样例相关文件

本次测试中涉及到的代码和配置文件如下图所示:
JDK源码分析——SecurityManager安全管理器实例分析

其中java.policy是jdk默认的策略(只做参考,具体的路径参考前面的介绍),sjava.policy是自定义的安全策略文件,TestMain是测试代码文件

3.2 样例源码

TestMain.java

package com.mh.JavaExample.sm;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * 安全管理器测试类
 * ==========================
 * 1 首先创建test文件
 * 1.1 运行该测试,System.getSecurityManager()为空,所有操作可以正常进行
 * ==========================
 * 2 运行的配置安全管理器和安全策略文件,使用的是默认的安全管理器
 * (PS:需要注意的是-Djava.security.policy,一个等号=代表同时也默认策略文件生效:java.policy
 *  两个等号==代表只使用后面的策略文件,不是用默认的策略文件)
 *     VM options: -Djava.security.manager -Djava.security.policy="...\JavaExample\src\test\resources\conf\sjava.policy"
 * 2.1 可以看到输出结果是必一样的,详情参考博客:
 */
public class TestMain {

    public static void main(String[] args) {
        // 获取系统的SecurityManager
        System.out.println("系统当前的安全管理器:"+System.getSecurityManager());

        String testFile = "C:\\Users\\Administrator\\Desktop\\fileTest.txt";
        try {
            FileInputStream fis = new FileInputStream(testFile);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try{
            // 正常读取(相关权限已经在java.policy中配置)
            // -Djava.security.policy= 这样配置的时候不抛异常
            // -Djava.security.policy==这样配置的时候会抛异常
            System.out.println(System.getProperty("java.version"));
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

        try{
            // 读取异常(相关权限没有进行配置,需要在sjava.policy中配置)
            System.out.println(System.getProperty("file.encoding"));
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

4 调试分析

下面将通过几种运行方式来深入分析jdk的安全机制的运行原理:

运行条件 预估输出
(1)直接运行(不带任何vm_options参数) 正常运行,不会抛出任何异常
(2)配置默认安全管理器 抛出异常:1、文件读取异常;2、读取系统属性文件编码异常
(3)配置默认安全管理器;配置自定义安全策略(=:和默认安全策略文件同时生效) 正常运行
(4)配置默认安全管理器;配置自定义策略(==:默认安全策略文件不生效) 读取java.version异常

4.1 直接运行(无参数)

运行输出

系统当前的安全管理器:null
1.8.0_171
UTF-8

4.2 配置默认安全管理器

运行输出

系统当前的安全管理器:java.lang.SecurityManager@77459877
access denied ("java.io.FilePermission" "C:\Users\Administrator\Desktop\fileTest.txt" "read")
1.8.0_171
access denied ("java.util.PropertyPermission" "file.encoding" "read")

4.3 配置默认管理+自定义策略文件(=)

默认策略文件java.policy生效,正常输出:

系统当前的安全管理器:null
1.8.0_171
UTF-8

4.4 配置默认管理+自定义策略文件(==)

运行输出:

系统当前的安全管理器:java.lang.SecurityManager@38af3868
access denied ("java.util.PropertyPermission" "java.version" "read")
UTF-8