一个例子理解AccessController.doPrivileged
2009-06-25 16:24
351 查看
示例中需要在eclipse中创建2个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);
eb6c
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
"
);
}
}
运行这个例子的时候,会出现权限错误,把doService()修改一下,就可以顺利通过
public
void
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:
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
加入一个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的角色)。
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);
eb6c
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
"
);
}
}
运行这个例子的时候,会出现权限错误,把doService()修改一下,就可以顺利通过
public
void
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:
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
加入一个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的角色)。
相关文章推荐
- 一个例子理解AccessController.doPrivileged()
- 一个例子理解AccessController.doPrivileged()
- SecurityManager一:理解AccessController.doPrivileged()
- 对AccessController.doPrivileged一点了解
- java 的 AccessController.doPrivileged使用
- java 的 AccessController.doPrivileged使用
- AccessController.doPrivileged 小记
- java 的 AccessController.doPrivileged使用
- 关于AccessController.doPrivileged、PrivilegedExceptionAction
- AccessController.doPrivileged解释
- AccessController.doPrivileged
- 关于AccessController.doPrivileged
- AccessController.doPrivileged 小记
- java AccessController.doPrivileged使用
- AccessController.doPrivileged
- AccessController.doPrivileged
- AccessController.doPrivileged 小记
- AccessController.doPrivileged
- 【转】关于AccessController.doPrivileged
- Spring源码--关于AccessController.doPrivileged