[Java/JVM/安全] ProtectionDomain : Java 安全模型的核心组件
概述: ProtectionDomain : Java 安全模型的核心组件
组件简介
java.security.ProtectionDomain是Java安全模型中的核心概念,主要用于封装代码的“来源”和“权限”,实现细粒度的访问控制。
- 自 JDK 1.2 起即支持此组件
主要作用
1. 定义代码的“来源”与“签名者”
- 来源(CodeSource):由代码的位置(URL)和数字证书(签名者)组成,用于标识“这段代码是谁写的、从哪里加载的”。
- 例如:一个从
https://example.com/下载的、被某公司签名的 JAR 包,其ProtectionDomain会记录这些元数据。
2. 绑定代码的权限(Permissions)
ProtectionDomain内部包含一个PermissionCollection(权限集合),明确指定这段代码允许做什么(如读写文件、访问网络等)。- 当代码尝试敏感操作时(如读取
/etc/passwd),Java 安全机制会检查该代码对应的ProtectionDomain是否有对应权限。
3. 实现“沙箱”隔离
-
不同来源的代码拥有不同权限:例如浏览器中的 Applet(已过时)或企业应用中的插件,通过为每个
ProtectionDomain分配不同权限,实现最小权限原则。 -
示例场景:
- 本地系统库的
ProtectionDomain拥有所有权限(AllPermission)。 - 远程下载的未签名代码的
ProtectionDomain只有有限权限(如无法访问本地文件)。
- 本地系统库的
4. 支持动态策略(Policy)
-
Java 的
Policy类(通过java.security.policy文件配置)会根据ProtectionDomain的CodeSource动态分配权限。 -
例如:
grant signedBy "trusted_vendor", codeBase "https://example.com/*" {
permission java.io.FilePermission "/tmp/*", "read,write";
};
5. 与 AccessController 协同工作
-
当代码调用
AccessController.checkPermission(...)时,JVM 会遍历当前调用栈中所有ProtectionDomain,只要有一个权限不足,就抛出AccessControlException。 -
这种机制防止了“权限提升攻击”(如不可信代码通过调用可信代码的敏感方法绕过限制)。
代码示例
// 获取当前类的 ProtectionDomain
ProtectionDomain domain = MyClass.class.getProtectionDomain();
System.out.println("CodeSource: " + domain.getCodeSource());
System.out.println("Permissions: " + domain.getPermissions());
最佳实践
CASE 获取本JAR包的所处目录
/**
* 获取应用程序JAR包所处路径
* @param applicationClazz 应用程序的 Class 类
* 1. 不能是 JDK 的 Class 类,例如: Object.class , Class.class , ... (将报错)
* @return
* "D:\Workspace\CodeRepositories\xxx-platform\xxx-sdk\xxx-sdk-helper\target" (源码工程在运行时的获取结果)
* "D:\Workspace\Projects\XXX-Project\xxx-sdk-helper-1.0.0-SNAPSHOT-jar-with-dependencies.jar" (JAR包在运行时的获取结果)
*/
public static String getApplicationJarDirectory(Class applicationClazz){
// 获取当前类的 ProtectionDomain
ProtectionDomain domain = applicationClazz.getProtectionDomain();//只能是应用工程的自定义类,不能是 jdk 的 类(如: Object.class , Class.class)
URL location = domain.getCodeSource().getLocation();
File jarFile = null;
try {
// 转换为文件路径
jarFile = new File(location.toURI());
//String jarDirectory = jarFile.getParent(); // JAR 所在目录
} catch (Exception exception) {
log.error("get current jar path fail !exception:", exception);
}
log.info("current jar path: {}", jarFile.getAbsolutePath());//"file:/D:/Workspace/CodeRepositories/xxx-platform/xxx-sdk/xxx-sdk-helper/target/classes/" or "D:\Workspace\Projects\XXX-Project\xxx-sdk-helper-1.0.0-SNAPSHOT-jar-with-dependencies.jar"
return jarFile == null ? null : jarFile.getParentFile().getAbsolutePath();
}
总结
ProtectionDomain是 Java 安全架构的“守门员”,通过将代码来源、签名者与权限绑定,确保只有受信任的代码才能执行敏感操作,是实现细粒度安全策略的基础。
Y 推荐文献
X 参考文献
本文作者:
千千寰宇
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号