Java安全机制
Java 安全机制是针对程序在操作本地资源时的权限限制,避免在执行有害代码时 (例如网络上下载的 jar 包)导致不可预估的损失。
这里简单介绍下使用方法。
配置安全策略
-
创建以
.policy
结尾的文件 -
配置授权规则,可以参考 Java 默认的策略文件
${java.home}/jre/lib/security/java.policy
以下面配置文件的语法为例
grant codebase "file:${user.dir}/-" {
permission java.io.FilePermission "${user.home}/*", "write";
};
其中定义了一条对 ${user.dir}/permission/
路径下所有文件的权限,规定对 ${user.home}
路径下一层级的文件拥有写入权限。
codebase "url"
为可选项,表示权限规则的授予目标,不设置则对所有文件生效。也可使用
其他目标语法,或者自定义语法。
permission
表示一条权限规则,后面需跟随 继承 Permission
类的全路径类名、构造方法参数,以 ;
结尾,可设置多条规则。
- 设置策略文件
-
追加策略文件 -Djava.security.policy=my.policy
-
替换策略文件 -Djava.security.policy==my.policy
开启安全机制
一般开启安全机制的方式有两种,设置 JVM 参数,或者通过代码配置。
配置 JVM Options
-Djava.security.manager
-Djava.security.policy=my.policy
代码设置
static {
String dir = System.getProperty("user.dir");
System.setProperty("java.security.policy", dir + "/my.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
}
注意在使用代码时会与 JVM Options
方式冲突,抛出 java.security.AccessControlException: access denied
异常信息,需要配置权限规则解决,可以选择追加在 Java 策略文件里。
grant {
permission java.lang.RuntimePermission "setSecurityManager";
permission java.util.PropertyPermission "java.security.policy", "write";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.util.PropertyPermission "user.dir", "read";
};
跳过权限检查
对于开启了安全策略后又不想定义权限规则时,则可以使用 AccessController
类的 doPrivileged
方法,跳过 checkPermission
步骤,直接调用方法体。
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
...
return null;
}
});
那么你可能会想,这样在其他依赖中也调用此方法不是绕过了安全机制。其实并不会,Java 在打包时会对实现了 PrivilegedAction
接口的元类信息进行清除,强制调用则会抛出 java.lang.NoClassDefFoundError
。
第三方工具
如果觉得默认的策略规则配置太繁琐了,那么可以使用 pro-grade
这个第三方依赖,他通过自定义语法简化了规则的配置,具体步骤可以参考
官网
<dependency>
<groupId>net.sourceforge.pro-grade</groupId>
<artifactId>pro-grade</artifactId>
<version>1.1.3</version>
<scope>compile</scope>
</dependency>