jdk-accessController

本文深入探讨了Java安全模型,解释了AccessController.doPrivileged的作用及其如何帮助代码在受限制环境中获得临时特权。同时介绍了Java安全机制的发展历程及最新概念。
在很多jdk源码中看到AccessController.doPrivileged,一直不知道这个类有什么作用,这次看common-logging源码时,加载classloader时又看到这个类,遂决定看下这个类的作用。
简单来说,允许一个类实例的买吗,通知这个AccessController,不用进行checkPermission检查。
复杂来讲要扯到java的安全模型:https://www.ibm.com/developerworks/cn/java/j-lo-javasecurity/


java将执行程序分为本地和远程两种,本地代码默认为可信任,远程代码不可信。本地代码可以访问一切本地资源,远程代码在jdk1中限制在沙箱中,这部分java代码限定在jvm特定的运行范围,并严格限制对本地系统的资源访问。
但这样太严格,远程代码无法访问本地系统文件。于是增加安全策略,允许用户制定代码对本地资源的访问权限。
最新的安全机制,引入域的概念,虚拟机会把代码加载到不同的系统域和应用域,不同的域具有不同的权限。


最常用的API是doPrivileged方法,它能够使一段受信任代码获得更大的权限,可以临时访问资源。
jdk中与安全相关的类都放在java.security中
### JDK 21中 `AccessController.doPrivileged` 的替代方案 在JDK 21中,随着Java安全模型的演进和模块化系统的引入(如JPMS),`AccessController.doPrivileged` 的使用场景逐渐减少,并且其功能可以通过更现代的方式实现。以下是几种可能的替代方案或更新方法: #### 1. 使用 `SecurityManager` 和权限检查 如果目标是绕过权限检查以执行某些操作,可以考虑通过显式设置权限来避免使用 `doPrivileged`。例如,在代码中明确声明所需的权限,而不是依赖特权块[^3]。 ```java Permission perm = new FilePermission("/1.txt", "read"); AccessController.checkPermission(perm); System.out.println("TestService has permission"); ``` #### 2. 利用模块化系统(JPMS)的权限控制 从Java 9开始引入的模块化系统(JPMS)提供了更精细的权限控制机制。通过配置模块描述符(`module-info.java`),可以明确指定模块之间的访问权限,从而减少对 `doPrivileged` 的需求[^5]。 例如: - 在模块A中导出特定包:`exports com.example.moduleA to com.example.moduleB;` - 在模块B中要求访问模块A的包:`requires com.example.moduleA;` 这种方式可以替代传统的权限提升需求,确保模块间的安全性和隔离性。 #### 3. 使用 `MethodHandles.Lookup` 实现反射调用 在某些情况下,`AccessController.doPrivileged` 用于执行特权反射操作。JDK 17及更高版本引入了 `MethodHandles.Lookup` 的增强功能,允许更安全地进行反射调用,而无需依赖特权块[^4]。 示例代码: ```java import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; public class ReflectionExample { public static void main(String[] args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.privateLookupIn( TargetClass.class, MethodHandles.lookup() ); var method = lookup.findVirtual(TargetClass.class, "privilegedMethod", MethodType.methodType(void.class)); method.invoke(new TargetClass()); } } class TargetClass { private void privilegedMethod() { System.out.println("Executing privileged method"); } } ``` #### 4. 明确声明特权操作 对于需要执行特权操作的场景,建议直接在代码中声明特权需求,而不是隐式地通过 `doPrivileged` 提升权限。例如,通过命令行参数或配置文件明确指定所需的权限[^1]。 ```bash java -Djava.security.manager -Djava.security.policy=policy.file MainClass ``` #### 5. 使用 `VarHandle` 替代部分特权操作 从JDK 9开始引入的 `VarHandle` 提供了一种高效、类型安全的方式来访问变量,可以替代某些需要特权操作的场景。例如,原子操作可以通过 `VarHandle` 实现,而无需依赖 `doPrivileged`[^2]。 示例代码: ```java import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; public class VarHandleExample { static class Counter { volatile int value; } public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { VarHandle vh = MethodHandles.lookup().findVarHandle(Counter.class, "value", int.class); Counter counter = new Counter(); vh.getAndAdd(counter, 1); // 原子增加 System.out.println(counter.value); } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值