示例中需要在eclipse中創(chuàng)建2個(gè)project:ServiceCentre和TestService
java.policy

grant codeBase "file:/D:/Workspaces/ExchangeConnect_V2_Trunk_Maven_workspace/ServiceCentre/bin/*"
{
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
package test;

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盤
package test;

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");
}

}
運(yùn)行這個(gè)例子的時(shí)候,會(huì)出現(xiàn)權(quán)限錯(cuò)誤,把doService()修改一下,就可以順利通過

public void doService()
{

// doFileOperation();


AccessController.doPrivileged(new PrivilegedAction()
{

public Object run()
{
doFileOperation();
return null;
}
});
}
在這個(gè)例子中AccessControlContext的stack順序?yàn)?br />
2. file:/D:/Workspaces/ExchangeConnect_V2_Trunk_Maven_workspace/ServiceCentre/bin/*
1 . file:/c:/TestService-1.0.jar
2沒有權(quán)限,1有權(quán)限,使用doPrivileged后,不檢查2
看一下java.security.AccessController的JavaDoc:
A caller can be marked as being "privileged" (see doPrivileged and below). When making access control decisions, the checkPermission method stops checking if it reaches a caller that was marked as "privileged" via a doPrivileged call without a context argument (see below for information about a context argument). If that caller's domain has the specified permission, no further checking is done and checkPermission returns quietly, indicating that the requested access is allowed. If that domain does not have the specified permission, an exception is thrown, as usual.
其中提到的no further checking is done的意思是指stack中的checking
加入一個(gè)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順序?yàn)?nbsp; 1->2->3
如果doPrivileged是在2中調(diào)用,那么1,2需要具有權(quán)限,3不再進(jìn)行檢查
如果doPrivileged是在1中調(diào)用,那么1需要具有權(quán)限,2,3不再進(jìn)行檢查
總結(jié):
1. 這里容易理解錯(cuò)誤的地方是checking順序,例如一個(gè)調(diào)用鏈 MethodA->MethodB->MethodC(這里的3個(gè)方法需要在3個(gè)不同的ProtectionDomain中),doPrivileged在MethodB中,很容易理解成檢查A,B而不檢查C,實(shí)際上stack中檢查順序?yàn)镃->B->A,也就是檢查C,B而不檢查A
2. ServiceCentre不需要太多權(quán)限,而Service就需要使用doPrivileged來避免受到ServiceCentre的權(quán)限限制(如果service有足夠的權(quán)限),Equinox中有很多這樣的例子(Equinox扮演Service的角色)。
posted on 2009-03-11 12:44
Phrancol Yang 閱讀(6753)
評(píng)論(1) 編輯 收藏