AccessController.checkPermission和doPrivileged示例

58 篇文章 0 订阅

 AccessController.checkPermission和AccessController.doPrivileged的示例

目录

checkPermission

doPrivileged


先来看普通情况

checkPermission

public class TestManager{
	public static void main(String[] args) throws FileNotFoundException {
		FileInputStream in = new FileInputStream(new File("D:\\1.txt"));
		System.out.println("有权限了!");	
}
}

在启动参数中使用-Djava.security.manager 之后,开启了SecurityManager,FileInputStream实例化时获取SecurityManager并检验是否有权限操作

    public FileInputStream(File file) throws FileNotFoundException {
	String name = (file != null ? file.getPath() : null);
	SecurityManager security = System.getSecurityManager();
	if (security != null) {
       // 这里边封装了一个new FilePermission(file,“read”)
       // 调用AccessController.checkPermission进行检验
	    security.checkRead(name);
	}
        if (name == null) {
            throw new NullPointerException();
        }
	fd = new FileDescriptor();
        fd.incrementAndGetUseCount();
	open(name);
    }

报错如下

Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission D:\1.txt read)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
	at java.security.AccessController.checkPermission(AccessController.java:549)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
	at java.io.FileInputStream.<init>(FileInputStream.java:113)
	at com.dw.acc.auto.tysl.TestManager.main(TestManager.java:11)

权限从哪来,从JAVA_HOME\jre\lib\security路径下java.policy设置,初始如下


grant codeBase "file:${{java.ext.dirs}}/*" {
	permission java.security.AllPermission;
};


grant { 
	permission java.lang.RuntimePermission "stopThread";
	
	permission java.net.SocketPermission "localhost:1024-", "listen";

	permission java.util.PropertyPermission "java.version", "read";
	permission java.util.PropertyPermission "java.vendor", "read";
	permission java.util.PropertyPermission "java.vendor.url", "read";
	permission java.util.PropertyPermission "java.class.version", "read";
	permission java.util.PropertyPermission "os.name", "read";
	permission java.util.PropertyPermission "os.version", "read";
	permission java.util.PropertyPermission "os.arch", "read";
	permission java.util.PropertyPermission "file.separator", "read";
	permission java.util.PropertyPermission "path.separator", "read";
	permission java.util.PropertyPermission "line.separator", "read";

	permission java.util.PropertyPermission "java.specification.version", "read";
	permission java.util.PropertyPermission "java.specification.vendor", "read";
	permission java.util.PropertyPermission "java.specification.name", "read";

	permission java.util.PropertyPermission "java.vm.specification.version", "read";
	permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
	permission java.util.PropertyPermission "java.vm.specification.name", "read";
	permission java.util.PropertyPermission "java.vm.version", "read";
	permission java.util.PropertyPermission "java.vm.vendor", "read";
	permission java.util.PropertyPermission "java.vm.name", "read";
	
};

 现报错D:\1.txt没有读权限,给他最后一添上

permission java.io.FilePermission "D:\\1.txt", "read";

之后就不报错了,要是一劳永逸,则改成

permission java.security.AllPermission;

所有权限支持

 

doPrivileged

情景:程序A调用了Bjar包来读取1.txt文件

在开启了安全管理器的情况下,只有当A和B都具有1.txt的操作权限时,才能过检测,安全检测是从调用栈顶到栈底依次检测,此情景下就是先检测Bjar包是否有操作这个文件的权限,再检测程序A是否有,两个都有,则过检测,否则报错

程序A代码如下:

public class MainTest {

	public static void main(String[] args) throws Exception {
		Test1 test1 = new Test1();
		test1.test();
		System.out.println("有权限");
	}
}

Bjar包代码:写两个类是当时想测试同包下两个类保护域是怎么情况

public class Test1 {
	public void test() throws FileNotFoundException {
		Test2 d = new Test2();
		d.test();
	}
}


public class Test2 {
	public void test() throws FileNotFoundException {
		FileInputStream fin = new FileInputStream(new File("D:\\1.txt"));
	}
}

程序A引入Bjar包,当然直接运行是不行的,会报错access denied ,在java.policy文件中配置如下才能正确运行

grant codeBase "file:/D:/Workspaces/XXX/target/classes/*" {
      permission java.io.FilePermission "D:\\1.txt", "read";
};


grant codeBase "file:/D:/java/maven/repository/com/X/B.jar" {
      permission java.io.FilePermission "D:\\1.txt", "read";
};

为什么要配置两个codeBase,因为程序A和jar包B,属于两个保护域(这玩意是啥我暂时说不清楚.......),这也可以Debug在检测权限那段代码发现,context数组是两个保护域,循环检测当前这个保护域是否有这个权限

public final class AccessControlContext {

    private ProtectionDomain context[];

   public void checkPermission(Permission perm) throws AccessControlException{
       for (int i=0; i< context.length; i++) {
            if (context[i] != null &&  !context[i].implies(perm)) {
                throw new AccessControlException("access denied "+perm, perm);
            }
        }
    }
}

再继续改造,将B包内的代码改改重新打包引入

public class Test2{
	public void test() throws FileNotFoundException, PrivilegedActionException {
		// FileInputStream fin = new FileInputStream(new File("D:\\1.txt"));

		FileInputStream fin2 = AccessController.doPrivileged(new PrivilegedExceptionAction<FileInputStream>(){

			@Override
			public FileInputStream run() throws FileNotFoundException {
				// TODO Auto-generated method stub
				return new FileInputStream(new File("D:\\1.txt"));
			}

		});
	}
}

AccessController.doPrivileged可以中断栈检查过程,B中调用这个操作,检查了B中是否有权限,如果B有就认为当前操作没问题,不再检查程序A中是否有权限,这种情况java.policy文件就可以只配置一个

grant codeBase "file:/D:/java/maven/repository/com/X/B.jar" {
      permission java.io.FilePermission "D:\\1.txt", "read";
};

这样即使A中没有1.txt的操作权限,程序也能正常运行

 

如果想要查看程序运行时,都检测了哪些权限,可以自定义SecurityManager类,如下操作

首先自定义类,调用父类方法,加个打印

public class MySecurityManager extends SecurityManager {
	 public void checkPermission(Permission perm) {
	  System.out.println("perm=" + perm);
	  super.checkPermission(perm);
	 }
}

java.policy文件加上  

permission java.security.AllPermission;

main方法启动时参数  

-Djava.security.manager=com.xxxx.xxx.MySecurityManager

接下来就可以看到打印出的各种权限

perm=(java.util.PropertyPermission java.system.class.loader read)
perm=(java.lang.RuntimePermission modifyThreadGroup)
perm=(java.lang.RuntimePermission modifyThread)
perm=(java.lang.RuntimePermission modifyThreadGroup)
perm=(java.lang.RuntimePermission modifyThread)
perm=(java.lang.RuntimePermission modifyThreadGroup)
perm=(java.lang.RuntimePermission modifyThread)
perm=(java.lang.RuntimePermission modifyThreadGroup)
perm=(java.lang.RuntimePermission modifyThread)
perm=(java.lang.RuntimePermission modifyThreadGroup)
perm=(java.lang.RuntimePermission modifyThread)
perm=(java.util.PropertyPermission java.vm.specification.version read)
perm=(java.util.PropertyPermission java.vm.specification.name read)
perm=(java.util.PropertyPermission java.vm.specification.vendor read)
perm=(java.util.PropertyPermission java.vm.version read)
perm=(java.util.PropertyPermission java.vm.name read)
perm=(java.util.PropertyPermission java.vm.vendor read)
perm=(java.util.PropertyPermission java.vm.info read)
perm=(java.util.PropertyPermission java.library.path read)
perm=(java.util.PropertyPermission java.class.path read)
perm=(java.util.PropertyPermission java.endorsed.dirs read)
perm=(java.util.PropertyPermission java.ext.dirs read)
perm=(java.util.PropertyPermission java.version read)
perm=(java.util.PropertyPermission java.home read)
perm=(java.util.PropertyPermission sun.boot.class.path read)
perm=(java.util.PropertyPermission sun.boot.library.path read)
perm=(java.util.PropertyPermission java.home read)
perm=(java.util.PropertyPermission com.oracle.usagetracker.config.file read)
perm=(java.io.FilePermission D:\JDK6\jre\lib\management\usagetracker.properties read)
perm=(java.io.FilePermission D:\JDK6\jre\lib\management\usagetracker.properties read)
perm=(java.util.PropertyPermission sun.jnu.encoding read)
perm=(java.io.FilePermission D:\MyEclipse\WorkSpaces*****\tysl\TestManager.class read)
perm=(java.io.FilePermission D:\MyEclipse\WorkSpaces*****\tysl\TestManager.class read)
perm=(java.io.FilePermission D:\MyEclipse\WorkSpaces*****\tysl\TestManager.class read)
perm=(java.io.FilePermission D:\MyEclipse\WorkSpaces*****\tysl\TestManager.class read)
perm=(java.io.FilePermission D:\MyEclipse\WorkSpaces*****\tysl\TestManager.class read)
perm=(java.io.FilePermission D:\1.txt read)
perm=(java.io.FilePermission D:\1.txt read)
perm=(java.io.FilePermission D:\1.txt read)
有权限了!

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值