简介
Globus Toolkit 3.0 (GT3) 是开放网格服务基础设施(Open Grid Service Infrastructure, OGSI)的参考实现。其中提供了基于开放网格服务架构(Open Grid Service Architecture, OGSA)和 Web 服务架构构建网格服务的基础平台。这些服务可以实现资源共享、任务日程安排与组织,还可以访问网格上的各种分布式资源。对于网格环境中的应用程序来说,安全性是极其重要的。我们需要根据组织机构以及其他一些不同的策略,来控制对资源和数据的访问。因此,网格服务和客户端需要相互进行认证,而且必须访问经过授权的服务。OGSA 安全架构仍然处在开发阶段;所以,GT3 中的某些与安全性有关的 API 将来可能会发生变化。本文的内容基于最新的稳定版本 Globus Toolkit 3.0 。文中相当详细地介绍了网格服务与客户端的编写,并着重强调了安全机制。所以,本文假定您了解网格服务的基本术语,如通知(notification)、服务数据(service data),等等。我们鼓励您用 GT3 编写一个简单的网格服务。GT3 中的程序员教程是很好的起点。
Globus Toolkit 的安全机制
GT3 的安全机制与以前的版本一样,也是基于公钥基础设施(Public Key Infrastructure, PKI)。PKI 系统是一种信任层次系统,参与其中的实体通过其持有的证书,以及事前建立的软件与过程,实现身份的标识和确认。公钥的认证一般遵从 X.509 标准。对于基于 Globu 的安全网格服务和客户端而言,这意味着所有参与的实体(包括服务和客户端)都要具备一个符合 X.509 格式的身份标识。您可能已经有了由公司使用的 X.509 认证标识,或是 Globus Toolkit 以前版本中使用的 Globus 认证标识。有很多的商用产品都可以用来为网格建立认证中心(Certification Authority, CA)。然而,最简单的方法就是使用 Globus 小组发布的 Simple CA 包了,它可以生成 CA,从而可以在 Globus 网格中发出证书。授权,或称访问控制,这项功能用于控制哪些用户可以访问系统中的哪些部分。GT3 的授权基于简单的访问控制列表,这个列表位于明文文件 gridmap 中。在任务提交的过程中,Globus Toolkit 2.0 用这个 gridmap 文件将用户映射为远程资源上的用户 ID。GT3 对这一思路进行了扩展,实现了对 factory 和服务的访问控制策略。gridmap 文件与服务和 factory 相关联,用于限制谁可以访问所提供的功能。
GT3 同时提供传输层和消息层的安全性。传输层的安全性依赖于对传输机制自身的保护。这种保护使得网格服务具有天生的安全性,但是却对传输形成依赖。消息级的安全性依赖于分别保护每一条消息。这样的机制很灵活,可以在任意的传输层之上发送消息。网格安全基础设施(Grid Security Infrastructure, GSI)基于公钥基础设施构建。在 Globus Toolkit 中,安全服务的基础是安全套接字层(Secure Socket Layer, SSL)。在 GT3 中,传输层安全性基于支持 GSI的HTTP 协议。消息层的安全性基于一些正在形成中的技术和标准,比如说 WS-Security、XML Encryption 以及 XML Signature 等。Globus Toolkit 正在朝消息级安全性的方向努力,而基于 GSI 的传输层安全性在将来的发布中可能会逐步淘汰,因此推荐应用程序使用消息级的安全机制。本文的其余部分将着重讨论消息级的安全机制。
Gridmap 文件的格式 gridmap 文件为每个可以访问网格服务的人包含了一个条目。每一行的格式如下:“可区分名称”用户 ID
gridmap 文件示例如下:
/O=Grid/O=Globus/OU=cnidr.org/CN=Lavanya Ramakrishnan"
lavanya "/O=Grid/O=Globus/OU=cnidr.org/CN=John Doe" john
开发安全的网格服务与客户端
本节中,我们将依次介绍用 GT3 编写安全网格服务所需的各个步骤。GT3 提供的机制可以对服务进行配置,使其使用认证和服务级授权。GT3 中带的 API 可以帮助程序员将其他的安全机制集成进来,或者进行更细粒度的访问控制。首先,我们将描述如何设置适合于安全架构的环境。然后,我们会看到如何通过认证和授权来限制对服务的访问。最后解释一下如何对这些配置进行扩展,以便为 factory 提供访问控制机制。下面带编号的四个小节中包含一些代码清单,您可以根据您自己的需要使用这些代码,或是进行修改。
1. 环境设置 GT3 提供的工具有助于您设置开发和部署网格服务的安全环境。请确认一下您是否已经用 $GLOBUS_LOCATION/bin/grid-cert-request 获取了相关证书。通常用户的私钥和公钥放置在主目录的 .globus 目录下。除此之外,您还需要创建 ~/.globus/cog.properties 文件。这个文件的内容应该是清单 1 中的格式。
清单 1. cog.properties 文件格式
usercert=/home/[username]/.globus/usercert.pem
userkey=/home/[username]/.globus/userkey.pem
proxy=/tmp/x509up_u[digit number]
cacert=/etc/grid-security/certificates/42864e48.0
usercert 和 userkey 两个变量指向公钥和私钥文件。在 GT3 中,您可以从长期的证据中派生出一个生命期更短的证据,供用户会话使用。这个较短期的文件称为 proxy(代理),生成的方法是使用 $GLOBUS_LOCATION/bin/grid-proxy-init,并在请求证书时使用密码短语(pass-phrase)。proxy变量指向这个代理文件。cacert 变量用于指向您所信任的 CA 证书。这些变量通常由 Globus 安装过程的 setup-gsi 脚本设置。 在启动任何一次网格会话之前,都不要忘记用 $GLOBUS_LOCATION/bin/grid-proxy-init 生成用户的代理。GT3 底层的安全库会找到这个用户代理,将其作为与这个用户运行的服务或者客户端相关联的代理(通过配置可使情况发生变化,稍后在清单 3 中将会讨论到)。GT3 的消息级安全是通过 Axis/JAX-RPC 处理程序实现的。server-config.wsdd 和 client-config.wsdd 必须定义适当的请求与响应流。默认情况下,GT3 会安装它们。
Sun JVM 问题 有些人已经知道,Sun JVM 1.4.0/1.4.1 的 xalan.jar 文件中存在一些问题。这个文件不能与 GT3 中使用的 xml-security 包协同工作。请参阅 XML Security Library 的 安装指南 ,找到解决这个问题的方法。如果您使用的是 J2SE 1.3.1 ,需要下载并安装 JAAS 库。
2. 编写安全的服务 本节中我们考虑一个简单的 HelloWorld 服务。HelloWorld 服务只有一个 sayHello() 方法,并可以订阅消息变化的通知。我们将告诉大家,如果想让这个 HelloWorld 变安全,应该进行哪些必需的修改。为了在服务实例上启用认证和授权,我们需要在部署描述符中设置若干属性,如清单 2 所示:
清单 2. 保护服务实例用到的部署描述符
<parameter name="instance-securityConfig"
value="org/globus/ogsa/impl/security/descriptor/gsi-security-config.xml"/
<parameter name="instance-authorization" value="gridmap"/
<parameter name="instance-gridmap" value="/home/lavanya/gridmap"/
instance-securityConfig 为安全属性指定部署描述符。这个参数用于在服务的安全属性之上提供粒度更细的控制。必须正确设置 instance-securityConfig 参数,认证才能生效。这里,我们将使用 GT3 提供的通用 gsi-security-config.xml 来实现 GSI 安全会话认证机制。您可以用可用的元素自己编写一个简单的安全描述符。安全部署描述符是从 classpath 处加载的;因此,您可以在实现该服务的 jar 文件中加入特定于应用程序的安全描述符。instance-authorization 参数定义了使用何种授权机制。可用的选项是 none、selfcode 和 gridmap 如果您在执行认证的时候没有初始化 instance-authorization,那么默认情况下执行 self 授权。
如果这些安全性参数是在 一节中定义的,那么就适用于容器中的所有服务。默认情况下,用户环境中底层的库会取出服务证据和已信任证书。但是您可以在部署描述符中为每一个服务单独配置一组证据和与之关联的已信任证书,如清单 3 所示。与此类似,您也可以用 containerProxy 参数或 containerCert 和 containerKey 两个参数来设置与容器关联的证据。
清单 3. 部署描述符中的其他选项
// To set the service credential
<parameter name="serviceProxy" value="[proxy file]"/
OR
<parameter name="serviceCert" value="[certificate file]"/
<parameter name="serviceKey" value="[unencrypted key file]"/
// To set the service trusted certificates
<parameter name="trustedCertificates" value="[CA certificate locations]"/
您可以按照一般网格服务的方式,根据 GWSDL 和 WSDL 生成服务的存根。在清单 4 中,我们展示了如何从服务的上下文中获取调用者的身份标识。清单中还阐明了其他一些可能的配置,服务端可能要求用这些配置设置安全通知回调。
清单 4. HelloWorldImpl.java 服务的实现
public class HelloWorldImpl extends GridServiceImpl implements
HelloWorldPortType, CredentialRefreshListener {
public helloWorldImpl() {
super("HelloWorld");
}
public String sayHello(String in0) throws java.rmi.RemoteException {
String identity = SecurityManager.getManager().getCaller();
System.out.println("The identity is "+identity);
Subject subject = JaasSubject.getCurrentSubject();
System.out.println("Jaas Subject is "+ subject);