http://huangyunbin.iteye.com/blog/1942509
AccessController.doPrivileged意思是这个是特别的,不用做权限检查.
在什么地方会用到呢:加入1.jar中有类可以读取一个文件,现在我们要使用1.jar去做这个事情.但是我们的类本生是没有权限去读取那个文件的,一般情况下就是眼睁睁的看着了.
但是jiava提供了doPrivileged.在1.jar中如果读取文件的方法是通过doPrivileged来实现的.就不会有后面的检查了,现在我们就可以使用1.jar去读取那个文件了.
例子:
把这个类打包成client.jar 放到/home/h/client/下
我们建立个my.policy文件,文件内容是:
配置文件的意思是 /home/h/client/下面的jar包或class类 可以读取/1.txt.
现在我们再创建一个项目:创建一个类来调用前面的Client
运行这个server类.注意这里要用上之前的my.policy文件
在vm参数中写上这样的:
运行,结果是
TestService has permission
在配置文件my.policy中我们没有允许server去读取/1.txt,但是现在却可以正常访问.这个就是 AccessController.doPrivileged的作用.
===http://www.blogjava.net/Phrancol/articles/259069.html
java.policy
permission java.io.FilePermission "c:/TestService-1.0.jar", "read";
permission java.lang.RuntimePermission "createClassLoader";
} ;
grant codeBase " file:/c:/TestService-1.0.jar " {
permission java.io.FilePermission "C:/text.txt", "read";
} ;
Project - ServiceCentre
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/** */ /**
* @author Donf Yang
*/
public class ServiceCentreMain {
public void loadService() {
URL[] urls;
try {
urls = new URL[] { new URL("file:c:/TestService-1.0.jar") };
URLClassLoader ll = new URLClassLoader(urls);
final Class a = ll.loadClass("test.TestService");
Object o = a.newInstance();
Method m = a.getMethod("doService", null);
m.invoke(o, null);
} catch (Exception e) {
e.printStackTrace();
}
}
/** *//**
* @param args
*/
public static void main(String[] args) {
ServiceCentreMain s = new ServiceCentreMain();
s.loadService();
}
}
Project - TestService
将TestService打包,放到C盘
import java.io.FilePermission;
import java.security.AccessController;
import java.security.Permission;
/** */ /**
* @author Donf Yang
*
*/
public class TestService {
public void doService() {
doFileOperation();
}
private void doFileOperation() {
Permission perm = new FilePermission("C:/text.txt", "read");
AccessController.checkPermission(perm);
System.out.println("TestService has permission");
}
}
运行这个例子的时候,会出现权限错误,把doService()修改一下,就可以顺利通过
// doFileOperation();
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
doFileOperation();
return null;
}
});
}
在这个例子中AccessControlContext的stack顺序为
2. file:/D:/Workspaces/ExchangeConnect_V2_Trunk_Maven_workspace/ServiceCentre/bin/*
1 . file:/c:/TestService-1.0.jar
2没有权限,1有权限,使用doPrivileged后,不检查2
看一下java.security.AccessController的JavaDoc:
其中提到的no further checking is done的意思是指stack中的checking
加入一个TestService2,文件操作在1,stack为(1,2,3为checking顺序)
3 . file:/D:/Workspaces/ExchangeConnect_V2_Trunk_Maven_workspace/ServiceCentre/bin/*
2 . file:/c:/TestService-1.0.jar
1. file:/c:/TestService2-1.0.jar
checking顺序为 1->2->3
如果doPrivileged是在2中调用,那么1,2需要具有权限,3不再进行检查
如果doPrivileged是在1中调用,那么1需要具有权限,2,3不再进行检查
总结:
1. 这里容易理解错误的地方是checking顺序,例如一个调用链 MethodA->MethodB->MethodC(这里的3个方法需要在3个不同的ProtectionDomain中),doPrivileged在MethodB中,很容易理解成检查A,B而不检查C,实际上stack中检查顺序为C->B->A,也就是检查C,B而不检查A
2. ServiceCentre不需要太多权限,而Service就需要使用doPrivileged来避免受到ServiceCentre的权限限制(如果service有足够的权限),Equinox中有很多这样的例子(Equinox扮演Service的角色)。