ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java高级特性——安全

2022-07-31 19:31:07  阅读:186  来源: 互联网

标签:Java permission xxx 高级 特性 管理器 java 权限 加载


Java高级特性——安全

Java技术提供了三种确保安全的机制:

  1. 语言设计特性(对数组的边界进行检查,无不受检查的类型转换,无指针算法)
  2. 访问控制机制,用于控制代码能够执行的操作
  3. 代码签名

一、类加载器

1. 类加载器介绍

类加载器可以在将类加载到虚拟机的时候检查类的完整性。
类加载器主要有三种:引导类加载器、平台类加载器、系统类加载器

  • 引导类加载器负责加载大量的 JDK 内部模块的平台类,如 StringBuilder、StringBuffer等。
  • 系统类加载器会从模块路径和类路径中加载应用类

2. 类加载器的层次结构

除引导类加载器外,其他的类加载器都有其父类加载器,层次结构如下图。根据规定,类加载器会为其父类加载器提供一个机会,以便加载任何给定的类。也就是说,当通过系统类加载器加载一个类 StringBuilder 时,它首先要求平台类加载器进行加载,而平台类加载器要求引导类加载器进行加载,如引导类加载器找到了这个类,那么它会加载这个类,而无需其他类加载器进行更多的搜索。

注:引导类加载器没有对应的 ClassLoader 对象
注:java9 之前可以通过反射机制访问受保护的URLClassLoader.addURLs 方法来加载 jar 包,但是现在无法这样操作了

3. 自定义类加载器

自定义类加载器继承 ClassLoader 类,实现其 findClass 方法即可。

protected Class<?> findClass(String name) throws ClassNotFoundException {
    try {
        // loadClassBytes 方法需自己实现
        byte[] classBytes = loadClassBytes(name);
        
        // defineClass 是 ClassLoader 内部方法
        Class<?> cl = defineClass(name,classBytes, 0, classBytes.length);
        if (cl == null) throw new ClassNotFoundException(name);
        return cl;
    } catch (IOExcetion e) {
        throw new ClassNotFoundException(name);
    }
}

4. 字节码校验

类加载器将字节码序列加载到虚拟机时,这些字节码首先要接受校验器的校验。校验器负责检查是否存在明显的有破坏性的指令。
检查项包括:

  • 变量要在使用之前进行初始化
  • 方法调用与对象引用类型之间要匹配
  • 访问私有数据和方法的规则没有被违背
  • 对本地变量的访问都落在运行时堆栈内
  • 运行时堆栈没有溢出
    注:可以通过虚拟机启动参数来关闭校验:java -noverify xxx

二、安全管理器与访问权限

注:Java 程序默认不开启安全管理器

1. 开启安全管理器

有两种方式可以开启安全管理器:

  • 通过启动参数(推荐)java -Djava.security.manager -Djava.security.policy==xxx.policy xxx
  • 在主程序中设置:System.setSecurityManager(new SecurityManager());

通过启动参数开启或者在主程序中设置时都可以选择指定策略文件,如果不指定,则使用默认的策略文件(位于 JDK 目录下的 conf/security 文件夹地下)
策略文件也可以通过代码指定(需在开启安全管理器之前指定),如下:

System.setProperty("java.security.policy", "/xxx/xxx.policy");
System.setSecurityManager(new SecurityManager());

一般来说,最好通过启动参数的方式来开启安全管理器和设置策略文件。

2. 安全策略文件

基本格式

// 代码来源是可选项,如果为空,则表示对所有来源的代码都授予下列权限
grant <代码来源> {
    permission 权限类型 "权限名称", "操作列表";
    permission 权限类型 "权限名称", "操作列表";
};

代码来源格式为:codeBase "file:///xxx/xxx.jar"
例子:

grant codeBase "http://www.horstmann.com/classes" {
    // 允许对/tmp目录及其子目录进行读写
    permission java.io.FilePermission "/tmp/-", "read,write";
    // 运行连接域名为 *.horstmann.com 和端口范围为 8000 到 9999 之间的 socket 服务
    permission java.net.SocketPermission "*.horstmann.com:8000-9999", "connect";
};

权限类型可参阅 java.security.permission 类的实现类。

3. 自定义权限

注:如果使用了 Java 平台模块,那么需要在 module-info.java 文件中导出自定义权限类所在的包,否则不生效
除了 JDK 提供的权限类之外,我们也可以自定义权限类。

(1)创建权限类

// TV 权限类
public class TVPermission extends Permission {
    ...
    ...
    // 当前权限是否隐含给定权限
    public boolean implies(Permission other) {}
}

(2)导出权限类所在的包

如果使用了模块,那么必须导出,这样安全模块才可以访问到该权限类。
module-info.java 文件

module xxx {
    exports com.fy.xxx.permissions;
}

(3)更新策略文件

grant {
    permission com.fy.xxx.permissions.TVPermission "tv", "watch";
}

(4)使用之前检查是否有权限

var manage = System.getSecurityManager();
var p = new TVPermission("tv","watch");
// 如果当前代码没有该权限,则这里会抛出 SecurityException 异常
if(manage != null) manage.checkPermission(p);

标签:Java,permission,xxx,高级,特性,管理器,java,权限,加载
来源: https://www.cnblogs.com/zolmk/p/16537924.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有