`
huxiaojun_198213
  • 浏览: 102806 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

RMI中的安全策略

    博客分类:
  • RMI
阅读更多
以下翻译来自Java RMI的Chapter 20.Security Policies

20.3 安全管理器

在一个运转的JVM中,权限是被SecurityManager的实例强制执行的。当一个程序试图做一些需要权限的事情时,就会通过查询SecurityManager的实例来检查此操作是否可以执行。举例来说,当试图从文件中读取数据时,将包含询问安全器程序是否允许从文件中读取数据的过程。

为了能看到实际效果,让我们看一下FileInputStream类的构造函数:


public FileInputStream(String name)throws FileNotFoundException{
  
   SecurityManager security = System.getSecurityManager();
 
   if(security!=null){
      security.checkRead(name);
   }
    
   fd  = new FileDescriptor();

   open(name);
}



构造函数的第一件事情是获取SecurityManager的实例,并询问文件是否可读。如果程序没有读取文件的权限,将会抛出异常。相似地,Socket的构造函数也会调用已安装的安全管理器来检查它是否被允许连接:

  private Socket(InetAddress address,int port,InetAddress localAddr,int localPort,boolean stream)throws IOException{
     this();
     if(port<0||port>0xFFFF){
        throw new IllegalArgumentException("port out range:"+port);
     }
     if(localPort<0||localPort>0xFFFF){
        throw new IllegalArgumentException("port out range:"+localPort);
     }
     SecurityManager security = System.getSecurityManager();
     if(security!=null){
       security.checkConnection(address.getHostAddress(),port);
     }
     ....
  }
 
 


但值得特别注意的是,如果没有安装SecurityManager的实例,那么权限检查将不会发生。这是一种一般性模式:程序只有在安装了管理器的情况下,才会执行权限检查,在没有安装的情况下,程序有权执行任何操作。

20.3.1 安装SecurityManager实例

在一个JVM中只能安装一个SecurityManager实例,并且此实例是不能被替换的。安装安全器最简单的方式是在运行JVM时设置java.security.manager系统属性,就像下面的示例一样:

java -Djava.security.manager application


上面的代码将会创建一个SecurityManager实例,在JVM启动之后,此实例将在特定应用程序开始运行之前安装。使用系统属性来安装安全器通常来说是非常便利的。举例来说,当我从Internet上下载了一个程序后,通常情况下我会从命令行安装一个安全管理器,其目的是限制恶意程序引发的损害。你也可以使用java.security.manager参数来指定一个特定的安全管理器,就像下面的代码一样:

java -Djava.security.manager=java.rmi.RMISecurityManager application


然而通常情况下,当你在编写一个RMI应用程序时,你可以通过调用System.setSecurityManager()来包含一个安全器。就像下面的代码一样:

System.setSecurityManager(new RMISecurityManager());


这样做的理由很简单:除非你的应用程序已经安装了SecurityManager实例,否则RMI的动态加载特性不会工作.如果你在使用动态加载时,依赖于用户或一个批处理文件,那么安装SecurityManager的实例是一个相当差的主意。

RMI提供了一个简单的安全管理器-RMISecurityManager(位于java.rmi.包下).在Java 2中,RMISecurityManager只是简单地继承标准安全器,其实现没有加入任何额外的功能。大部分RMI应用程序使用RMISecurityManager都基于两个非常简单的理由:

首先,RMISecurityManager而非标准安全管理器有效地记载了安装管理器的原因(因此,使得其他人在未经思考的情况下,通过修改代码来删除安全管理器的可能性就会变得很低)。

第二, 它会随着RMI的安全模型自动演变。如果你使用RMISecurityManager的实例,当其实现变得更精细的时候,你的代码也会自动演变。

20.3.2 安全管理器是如何工作的

正如我已经指明的,安全管理器是能通过电话交谈(call-in)策略来工作的。换句话说,每当可疑问题将要发生时,它都需要依赖于软件包来询问权限。安全顺序为:

1.请求安全检查的方法被调用

2.作为方法实现的一部分,被迫调用安全管理器。此调用通过抛出异常来表示发生了安全违反或通过默默地返回以允许原来的方法调用能够继续处理。

SecurityManager的实现为了检查是否允许一个操作,实际上做了许多的工作。它们首先检查调用SecurityManager的对象是否有适当的权限。注意,因为调用SecurityManager的对象是标准Java库中的某一部分,因此默认地它是有权限的。属标准Java库的所有类都有权限执行任何操作。但,它们必须检查他们是否能够执行请求的操作。在这之后,SecurityManager将遍历堆栈,检查堆栈里的每个类是否有合适的权限。如果其中任何一个没有权限的话,那么将检查失败并抛出异常。检查堆栈是安全机制中非常重要的一部分。除非整个堆栈都已经检查了,否则没有任何方式能直接地阻止敌对代码来初始化一个动作。

20.3.3 java.security.debug

在SecurityManager工作的时候,你可以通过设置java.security.debug系统属性来观察。此属性有四个基本值:all,access,policy,scl.

access是关于将要被打印到System.err的权限检查原因信息。access有三个高级版本:statck,domain和failure.access statck用于打印每次权限检查的信息。access domain打印堆栈中所有对象的域信息。access failure打印在堆栈或域中安全检查失败的信息。举例来说,在我们银行的程序中,通过下面的命令行来给出关于正在检查哪一个权限以及从哪检查的信息:

java -Djava.security.manager -Djava.security.debug = "access domain" com.ora.rmibook.chpter9.applications.BankClient.

20.4 设置安全策略

到目前为止,我们谈论的都是关于权限的基础思想,怎样检查它们以及强制执行。下一步我们讨论如何设置的。JVM是怎样查找出哪一个权限被授予了特定的类的呢?

20.4.1三个策略文件

在大部分情况下,当运行一个应用程序时,会用到下面的两个或三个安全策略文件:

1.全局策略文件

   这是一个适合于由任何一个用户启动的所有应用程序的策略文件。它要么是默认策略文件(随Java运行时环境出现),要么是由系统管理员定义的策略文件。终端用户很少修改此文件。默认情况下,全局策略文件安装在${java.home}/jre/lib/security/java.policy.

2.用户策略文件

   这是一个适合于由特定用户启动的所有应用程序的策略文件。它通常不存在(没有与JRE相关的特定用户的策略文件)或由系统管理员定义。终端用户很少修改此文件。用户策略文件有一个默认位置:${user.home}/.java.policy.

3.应用策略文件

   这是一个适合于特定应用程序的策略文件,它定义了应用程序为了能够正常运行所需要的权限。此策略文件没有默认位置。相反地,其文件位置必须在程序运行的时候,以系统参数的形式进行设置。

因为每个文件都列出了权限,使得将这些文件进行联合就变得很有意义。也就是说,只要这些文件中任何一个指明一个操作是被允许的话,那么此操作就是允许的。

20.4.1.1 设置特定应用的策略文件

应用程序策略文件是通过java.security.policy系统参数来定义的。也就是说,为了设置它,你可以像下面这样使用命令行来设置:


java -Djava.security.policy="d:\java.policy"



然而在没有安全器的情况下,这也没有太多的意义。如果一个JVM是通过安全策略调用的,那么就相当于从命令行安装了一个安全管理器,就像下面这样:
java -Djava.security.manager -Djava.security.policy="d:\java.policy"


也可以写成:
java -Djava.security.manager -Djava.security.policy=="d:\java.policy"


上述配置将会告知JVM只使用应用策略文件而忽略其他两个权限文件。

20.4.2 策略文件内部

一个策略文件由grant语句序列组成的。每个grant语句都有下面的格式:

grant [signedBy Name] [codeBase URL] {
       //list of persmissions
};

翻译过来就是:

任何一个从URL指定的codeBase加载的且使用Name数字签名的类,都要下列权限。

方括号表明是一个可选元素,单词"signedBy"和codeBase必须用在它们的参数前。因此,下面的全是正确的grant语句:

grant{
  // list of permissions
};

grant codeBase "http://www.oreilly.com/"{
  // list of permissions
}

grant signedBy WGrosso{
   // list of permissions
};

grant signedBy WGrosso codeBase "http://oreilly.com/"{
   // list of permissions
};



以下是一个较为完整的例子:


grant codeBase "file://d:/classes"{
   permission java.awt.AWTPermission "accessClipboard";
   permission java.awt.AWTPermission "accessEventQueue";
   permission java.awt.AWTPermission "listenTOALLAWTEvents";
   permission java.awt.AWTPermission "showWindowWithOutWarningBanner";
   permission java.awt.AWTPermission "readDisplayPixels";

   permission java.net.SocketPermission ":1024-","accept,connect,listen,resolve";

   permission java.net.FilePermission "<<ALL FILES>>","read";
   permission java.net.FilePermission "<<ALL FILES>>","write";
   permission java.net.FilePermission "<<ALL FILES>>","delete";
   
   permission java.util.PropertyPermission "*","read,write";

}


上面的配置允许从D:\classed目录加载的任何类操作GUI,使用非系统端口创建socket连接,操作文件,以及编辑系统属性对象。


20.4.3 在RMI中使用安全策略

在你的RMI应用程序中是没有必要使用安全管理器的,这只会影响到RMI的动态类加载特性.但是,RMI注册表和激活框架守护线程都要使用到安全策略.

如果你使用了这些服务中的任何一种,并且没有给它们一个专门的安全策略,那么你的应用程序将会以几种微妙的方式中断.考虑一个绑定一个使用定制socket的服务到RMI注册表中的例子.RMI注册表将包含一个指向原始服务器的stub实例.这个反序列化的stub将包含一个相关的socket.由于此相关的socket是定制socket类的实例,这说意味着java.net.socket构造函数的调用栈包含一个non-Javasoft的类.也就是说,除非RMI注册表拥有了一组更加不严格的权限,否则绑定会失败.

//////////////////////////////////////////////////////////////////////////////////

重申一下:-J标志是用来传递参数给底层JVM(包括RMI注册表和激活框架守护线程)的.比如,你必须使用下面的命令行来调用:
registry -J-Djava.security.policy="d:\classes"
//////////////////////////////////////////////////////////////////////////////////

因为动态类加载是非常有用的,又因为激活框架守护线程或注册表强制你无论如何都要编写一个安全管理器,因此RMI应用程序会使用一组相关的安全策略:服务端一个,命名服务一个,客户端一个.

20.4.4 策略工具
本章节因与JDK1.6中策略工具在界面上有一点出入,所以未翻译.想了解的朋友可以参考jdk1.6的安全指南.




分享到:
评论

相关推荐

    Rmi示例 Rmi代码示例

    4. **安全性**:RMI支持Java安全模型,可以通过配置安全策略来限制客户端对远程对象的访问权限。此外,还可以使用SSL/TLS等加密协议增强网络通信的安全性。 5. **RMI优化**:为了提高性能,开发者可以使用RMI的优化...

    rmi.rar_Java RMI_RMI java_RMI policy.all_rmi

    5. **RMI 安全性**:标签中提到了“rmi_policy.all”,这通常是指RMI的安全策略文件,用于控制RMI应用程序的权限。通过设置策略文件,可以限制远程对象的操作,确保系统的安全性。 6. **部署和运行**:使用RMI时,...

    RMI+EHCACHE Demo

    2. **RMI接口与实现**:定义远程接口,实现接口中的业务逻辑,并进行必要的RMI注解。 3. **服务器端代码**:启动RMI服务器,注册远程对象到RMI注册表,可能包含Ehcache的初始化和管理。 4. **客户端代码**:连接到...

    基于rmi的远程控制

    10. **部署与配置**:RMI应用需要正确配置JVM的RMI服务,包括设置RMIREGISTRY端口、JDK的`.policy`文件以指定安全策略,以及可能的防火墙或安全组规则。 在“基于RMI的远程控制”项目中,开发者可能创建了一个包含...

    精通RMI程序代码

    - **安全性**:RMI的安全性涉及SSL/TLS加密、数字签名以及访问控制,确保网络通信的保密性和完整性。 - **异常处理**:RMI中的异常通常包括网络连接问题、对象不存在、版本不匹配等,需要适当地捕获和处理。 - **...

    RMI教程-入门经典

    用户可以自定义安全策略来限制远程对象的访问。 7. **启动RMI服务**:在服务器端,需要通过 `rmiregistry` 工具启动RMI注册表,然后启动包含远程对象的服务器应用程序。 8. **客户端调用**:客户端通过 ` ...

    JAVA RMI简单例子

    默认情况下,RMI使用匿名连接,但在生产环境中,通常需要配置安全策略以限制远程调用的权限。 此外,RMI还可以与EJB(Enterprise JavaBeans)、JMS(Java Message Service)等企业级技术结合,构建更复杂的分布式...

    JAVA RMI测试代码

    - RMI支持SSL加密通信,可以通过配置`java.security.policy`文件来设定权限策略。 - 远程对象可以设置安全属性,限制客户端的访问权限。 5. **异常处理**: - `java.rmi.RemoteException`是最常见的RMI异常,...

    RMI示例程序,RMI学习

    在服务器端,`main`方法中设置了`RMISecurityManager`,这是RMI安全性的基础,确保只有被授权的代码才能执行远程方法。然后创建`HelloService`的实例,并将其绑定到"HelloServer"这个名字上,通过`Naming.rebind()`...

    rmi回调实例含代码

    8. `policy`: RMI的安全策略文件,定义了RMI操作的安全权限。 回调机制在RMI中的应用通常涉及服务器端调用客户端的方法。这通常发生在服务器需要客户端执行某些操作或提供反馈时。例如,在`StockQuoteServerImpl`中...

    Ehcache RMI Replicated Cluster(RMI集群)

    - **安全性**:RMI通信可能会暴露于网络攻击,因此需要考虑使用SSL/TLS加密通信,以及限制RMI端口的访问权限。 - **数据一致性**:虽然RMI提供了近乎实时的数据同步,但不保证完全的一致性。在设计系统时,需要考虑...

    web服务器 RMI meeting

    3. 安全性问题,如何在RMI调用中处理身份验证和加密,以防止未授权访问。 4. 性能优化,探讨如何通过负载均衡和缓存策略提高Web服务器在处理RMI请求时的效率。 5. 故障排查和监控,如何诊断RMI连接问题,以及如何...

    RMI CallBack

    远程方法调用(Remote Method Invocation,RMI)是Java中的一种机制,允许一个对象在某个JVM上执行另一个JVM...在实现过程中,需要理解并掌握RMI的原理,以及如何设计和实现回调接口及其实现,同时注意安全策略的配置。

    RMI远程下载文件

    6. **policy.txt**: RMI安全策略文件,用于定义客户端或服务器端的权限设置。在RMI应用中,可能需要配置此文件以允许特定的安全操作,比如文件I/O或网络通信。 综上所述,这个项目展示了如何使用Java RMI实现在远程...

    rmi client和server完整代码

    3. 安全性:RMI支持SSL加密和权限控制,可以配置安全策略文件以增强安全性。 五、运行示例 压缩包中的"client"和"server"目录分别包含了客户端和服务器的源代码。客户端代码会尝试连接到服务器,通过RMI注册表找到...

    java RMI简单Demo

    - **配置文件(如:rmiregistry.policy)**:可能包含RMI服务器的安全策略设置。 要运行这个RMI示例,首先确保JDK已经安装并且JVM支持RMI,然后按照以下步骤操作: 1. 编译所有源代码,生成对应的class文件。 2. ...

    Java RMI demo多对象

    - 可以使用Java安全策略来控制远程对象的访问权限。 5. **异常处理**: - `java.rmi.RemoteException`是最常见的RMI异常,通常表示网络或序列化问题。 - `NotBoundException`表示试图查找的远程对象未在注册表中...

    Eclipse RMI插件使用API

    ### Eclipse RMI插件使用API ...这些步骤不仅包括了插件的安装配置,还包括了创建服务器端和客户端的具体过程,以及必要的安全策略配置。掌握这些技能将有助于您更高效地利用RMI技术进行分布式系统的开发。

    Spring RMI

    **Spring RMI 深度解析** ...以上就是关于Spring集成RMI的相关知识点,包括基本概念、配置、优势、优化策略以及与Spring Boot的结合。通过理解和掌握这些内容,开发者可以更加高效地在分布式环境中构建和管理远程服务。

    java-RMI技术讲解

    - **`java.lang.SecurityManager`**:用于设置安全策略。 - **`java.rmi.Naming`**:用于名称解析。 - **`java.rmi.RMISecurityManager`**:提供额外的安全控制。 - **`java.io.IOException`**:表示I/O异常。 - **`...

Global site tag (gtag.js) - Google Analytics