java 的 AccessController.doPrivileged使用

http://huangyunbin.iteye.com/blog/1942509

AccessController.doPrivileged意思是这个是特别的,不用做权限检查.

在什么地方会用到呢:加入1.jar中有类可以读取一个文件,现在我们要使用1.jar去做这个事情.但是我们的类本生是没有权限去读取那个文件的,一般情况下就是眼睁睁的看着了.  

但是jiava提供了doPrivileged.在1.jar中如果读取文件的方法是通过doPrivileged来实现的.就不会有后面的检查了,现在我们就可以使用1.jar去读取那个文件了.


例子:

Java代码
package huangyunbin.client;

import java.io.FilePermission;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;

public class Client
{
    public   void  doCheck() {
                AccessController.doPrivileged( new  PrivilegedAction()  {
            public  Object run()  {
                check();
                return   null ;
            }
        } );
    }

    private   void  check()  {
        Permission perm  =   new FilePermission( "/1.txt" ,  "read" );
        AccessController.checkPermission(perm);
        System.out.println( " TestService has permission " );
    }
}



把这个类打包成client.jar 放到/home/h/client/下
我们建立个my.policy文件,文件内容是:

Java代码
grant codeBase  "file:/home/h/client/*"   {
     permission java.io.FilePermission  "/1.txt","read";
 };



配置文件的意思是 /home/h/client/下面的jar包或class类 可以读取/1.txt.


现在我们再创建一个项目:创建一个类来调用前面的Client

Java代码
public class server
{
    public static void main(String[] args)
    {
        Client c =new    Client();
        c.doCheck();
    }
}



运行这个server类.注意这里要用上之前的my.policy文件
在vm参数中写上这样的:


Java代码
-Djava.security.manager 
-Djava.security.policy=/home/h/my.policy



运行,结果是
TestService has permission

在配置文件my.policy中我们没有允许server去读取/1.txt,但是现在却可以正常访问.这个就是 AccessController.doPrivileged的作用.

 

===http://www.blogjava.net/Phrancol/articles/259069.html

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


}


运行这个例子的时候,会出现权限错误,把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的角色)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java.lang.IllegalStateException: mBeanFactory.removeContext.addServicedFail at org.apache.catalina.mbeans.MBeanFactory.removeContext(MBeanFactory.java:767) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:294) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468) at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) at java.security.AccessController.doPrivileged(Native Method) at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408) at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at sun.reflect.GeneratedMethodAccessor49.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值