Java安全机制

Java的安全模型默认是不启用的,需要通过设置SecurityManager来激活。安全策略文件默认位于${JAVA_HOME}/jre/lib/security/java.policy,也可自定义。在启用安全模型后,常用API如AccessController的doPrivileged()方法用于进行权限检查,允许指定代码段在特权上下文中运行,免于权限检查。
摘要由CSDN通过智能技术生成

启动

默认情况下,Java的安全模型是不启用的。为了使用Java的安全模型,需要通过初始化安全管理器(SecurityManager)来启用Java安全模型。

  • 编码式初始化SecurityManager
// 获取安全管理器,如果安全管理器未安装,则返回null
SecurityManager manager = System.getSecurityManager();
if (manager == null) {
  // 安装并初始化安全管理器
  System.setSecurityManager(new SecurityManager());
}
  • JVM启动参数初始化
-Djava.security.manager

没有安装安全管理器的情况下,调用System.getSecurityManager()返回的是null,即可根据 System.getSecurityManager() 返回结果是否为null来判断Java安全模型有没有启用

安全策略

当启用Java安全模式时,Java默认的安全策略文件为 ${JAVA_HOME}/jre/lib/security/java.policy

可以用JVM启动参数指定安全策略文件

-Djava.security.policy=/Users/developmac/workspace/develop/config/java.policy

使用

SecurityManager 提供了一系列供用户调用的API来做权限检查。SecurityManager的典型用法如下:

SecurityManager security = System.getSecurityManager();
if (security != null) {
    security.checkXXX(argument,  . . . );
}

一个文件读权限检查的例子

public class Test {
    public static void main(String ...args) throws Exception {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        System.getSecurityManager().checkRead("foo.txt");
    }
}

结果

Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "foo.txt" "read")
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
	at java.security.AccessController.checkPermission(AccessController.java:884)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
	at java.lang.SecurityManager.checkRead(SecurityManager.java:888)
	at java.io.FileInputStream.<init>(FileInputStream.java:127)
	at java.io.FileInputStream.<init>(FileInputStream.java:93)
	at org.learn.agent.security.ReadFile.main(ReadFile.java:15)

java.security.AccessController#doPrivileged(java.security.PrivilegedAction)

AccessController引入了一个doPrivileged()静态方法,只要Caller执行了doPrivileged()方法(注意:这里的Caller还是需要相应权限,但是Caller的Caller就不需要了,如果不用doPrivileged()方法,调用链上所有的Caller都需要权限),那么这个Caller就会被标记为privilege,Java安全模型就不会去检查这个Caller的权限。也就是说,调用doPrivileged()的Caller被授予了特权,这个Caller可以免去权限检查。在进行权限检查的时候,回溯调用链的过程中,一旦遇到被标记为privilege的Caller,那么AccessController将停止向上回溯,权限检查通过。

参考:

AccessController.doPrivileged的作用
java中的安全模型(沙箱机制)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值