【再探】Java—Java 沙箱机制与类加载器

2024-06-07 04:28
文章标签 java 加载 机制 沙箱

本文主要是介绍【再探】Java—Java 沙箱机制与类加载器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 沙箱(Sandbox)机制是将Java程序限定在JVM特定的运行范围内,并严格限制代码对本地系统资源的访问,以保证代码的有效隔离,防止对本地系统造成破坏。

1 安全模型

类在加载过程中,类加载器会为类设置初始的安全上下文(从安全策略文件读取权限配置信息),在类的执行过程中,会根据它所拥有的权限进行检查和授权。

安全管理器

SecurityManager是Java的一个组件。用于控制应用程序对系统资源的访问。

代码源

CodeSource,是确定一个特定代码源的原点,有两个字断,一个是代码路径URL(可以是包的位置,也可以是jar的位置),另一个是数字签名证书信息。

权限

Permission,用于授予或拒绝访问特定资源的权限。PermissionCollection类是一组Permission对象的集合。

这两个类都有implies(Permission)方法,用于检测是否拥有该权限。

策略

Policy,实现基于规则的访问控制和权限管理。定义了一组规则,用于确定哪些主体可以访问哪些对象。

保护域

ProtectionDomain,包含了代码源、权限集信息。Java中,每个类都会分配到一个保护域中。保护域会在类加载阶段进行设置。

图 安全模型中的几个重要概念

图 Java的安全模型

1.1 类加载过程中的授权及权限检测

  1. 当JVM需要使用一个类时,会委托给类加载器去加载这个类,来加载类的字节码,并将其转换为JVM可以理解的Class对象。
  2. 加载类时,类加载器会为这个类创建一个保护域(一个类只能在一个保护域中)。
  3. 权限集可以在类加载时静态设置,也可以在运行时动态修改。权限信息通常来自Java安全策略文件。此外还可以通过安全管理器的API在运行时动态授予和撤销权限。
  4. Java代码尝试执行受保护的操作(文件访问、网络访问、反射等)时,安全管理器会检察该代码相关联的保护域中的权限,如果没权限,则会抛出SecurityException异常。

1.2 安全策略文件

用于配置代码的执行权限。 可以使用-Djava.security.manager 命令行来指定Java安全策略文件。根据作用范围,分为全局策略及用户策略。

全局策略

作用整个Java虚拟机的安全策略,用于定于默认的安全规则。对所有Java应用程序生效。通常位于$JAVA_HOME/jre/lib/security/java.policy。

用户策略

是个可选的安全策略,用于定义应用程序的安全规则。

表 全局策略与用户策略

Java安全权限验证默认没开启,可以通过-Djava.security.manager来开启。但是可能会带来下面这些影响。

性能下降

JVM需要对每个可执行的代码进行安全性检查,从而可能会导致性能下降。

功能限制

功能可能会受到限制。如果没有配置良好的安全策略文件或者安全策略过于严格,则可能导致程序无法执行一些关键操作,例如访问本地文件系统,创建网络连接等。

需要额外的配置

需要编写和配置安全策略文件,要求程序员具有一定的安全意识和技能。

表 开启安全权限验证的影响

2 类加载器

每个类加载器都有自己的命名空间,这意味着由特定类加载器加载的类与其他类加载器加载的类在逻辑上是隔离的(除非这些加载器有明确的父子关系)。

类隔离

每个类加载器都有自己的命名空间,不同类加载器加载的同名类被视为不同的类。所以允许应用程序定义与标准库或第三方库同名的类,而不会发生冲突。

资源隔离

与类隔离同理。

安全性

会在加载过程中对类进行权限配置与验证。

表 类加载器的其他作用

2.1 自定义类加载器。

图 Java默认的三种加载器及协作关系

Java中加载类是用了“双亲委派模型”,即加载类时,先委托给父类加载器,如果父类加载器加载不了,则再自己处理。这里的父类并不是指具有继承关系的,而是通过合成复用,来设置父类加载器。

系统默认使用应用程序类加载器来加载类。(实际上还有许多的加载方式,例如通过远程加载等)

我们在自定义类加载器时,如果没有指定父类加载器,那么其父类加载器为应用程序类加载器。

public class CustomClassLoader extends ClassLoader{public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {ClassLoader classLoader = new CustomClassLoader();Class<?> aClass = classLoader.loadClass("com.huangmingfu.ReadFileObj");System.out.println(aClass.newInstance());}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] classByte = getClassByte(name);return defineClass(name.substring(0,name.lastIndexOf(".")),classByte,0,classByte.length);}private byte[] getClassByte(String name) {String filePath = getPath() + "/" + name;try(FileInputStream inputStream = new FileInputStream(filePath);) {ByteArrayOutputStream stream = new ByteArrayOutputStream();int i = 0;while ((i=inputStream.read()) != -1) {stream.write(i);}return stream.toByteArray();} catch (IOException e) {throw new RuntimeException(e);}}private static String getPath(){URL url = ClassLoader.class.getProtectionDomain().getCodeSource().getLocation();try {return URLDecoder.decode(url.getPath(),"UTF-8");} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}
}

2.1.1 sql驱动中的类加载器

Java 核心库(rt.jar)中包含了与数据库连接有关的接口。实际实现则需要数据库厂家自己提供的jar包(例如,mysql的mysql-connector-java)。通过SPI模式,当厂家的数据库驱动包包含到用户路径时,rt.jar的ServiceLoader 会去加载这个实现类,现在问题来了:

核心库是启动类加载器加载的,而厂家提供的jar包不能被其加载。在ServiceLoader 中,通过Thread.currentThread().getContextClassLoader(); 来获取上下文类加载器来加载厂家的实现类。

这篇关于【再探】Java—Java 沙箱机制与类加载器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038161

相关文章

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

springboot整合 xxl-job及使用步骤

《springboot整合xxl-job及使用步骤》XXL-JOB是一个分布式任务调度平台,用于解决分布式系统中的任务调度和管理问题,文章详细介绍了XXL-JOB的架构,包括调度中心、执行器和Web... 目录一、xxl-job是什么二、使用步骤1. 下载并运行管理端代码2. 访问管理页面,确认是否启动成功

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

Java中ArrayList的8种浅拷贝方式示例代码

《Java中ArrayList的8种浅拷贝方式示例代码》:本文主要介绍Java中ArrayList的8种浅拷贝方式的相关资料,讲解了Java中ArrayList的浅拷贝概念,并详细分享了八种实现浅... 目录引言什么是浅拷贝?ArrayList 浅拷贝的重要性方法一:使用构造函数方法二:使用 addAll(

解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题

《解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题》本文主要讲述了在使用MyBatis和MyBatis-Plus时遇到的绑定异常... 目录myBATis-plus-boot-starpythonter与mybatis-spring-b