- 浏览: 3503203 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wanglf1207:
EJB的确是个不错的产品,只是因为用起来有点门槛,招来太多人吐 ...
weblogic-ejb-jar.xml的元素解析 -
qwfys200:
总结的不错。
Spring Web Flow 2.0 入门 -
u011577913:
u011577913 写道也能给我发一份翻译文档? 邮件437 ...
Hazelcast 参考文档-4 -
u011577913:
也能给我发一份翻译文档?
Hazelcast 参考文档-4 -
songzj001:
DbUnit入门实战
摘要
在现今的IT领域,Web services变得日益重要,特别是随着面向服务的架构(SOA)的快速发展和应用。默认情况下,Web Services调用(请求和响应)采用纯文本通过HTTP之类的协议传送。虽然使用纯文本传送是考虑到更广泛的客户端互操作性,但是也带来了安全隐患。 本文讨论了这样做所招致的一些安全风险以及怎样应用BEA WebLogic Server的Web Services安全性实现避免这些风险。
本文由两大部分组成。第一部分概述消息完整性、消息机密性和身份验证,简短地讨论了怎样通过策略注释(policy annotation)加以实现。第二部分是一个教程,通过一个实例一步一步地指导读者构建一个基本的服务,然后添加消息的完整性、机密性和授权。
我们假定读者熟悉BEA WebLogic Server 9.2上的基本Web Services开发,以及诸如数字签名、数字加密等基本的安全概念。
Web Services和安全性概述
本节概述Web Services安全性的许多方面,包括消息的完整性、机密性和身份验证。如果您熟悉这些内容,那么可以跳过这一节,直接阅读 教程部分。
Web Services基础
一个基本的Web Services由两个组件组成:
- 服务的提供者——实际的服务,由服务容器提供。
- 服务的消费者——调用服务的客户端,既可以是本地的,也可以是远程的。
本文中,我们将假定服务的提供者是部署(和运行)在WebLogic Server 9实例上的一个基于Java的Web Services。服务的消费者将是位于本地或远端计算机上且运行在它自己的JVM中的一个Java客户端。
Web Services交互首先由客户端从服务提供者获得WSDL文件。WSDL文件包含客户端调用服务所需的服务和调用信息。一旦客户端有了WSDL文件,它 就能够向服务提供者发送一个纯文本SOAP请求消息(含有要调用的服务和任何参数等信息)来调用一个Web Services。服务提供者收到这个消息并解析它,然后进行处理。处理一结束,服务提供者就返回给客户端一个纯文本SOAP响应消息(含有所有的结果数 据)。
由此可见,纯文本SOAP是默认的传输协议。遗憾的是,这种协议非常容易受到各种安全性攻击。我们要求助于WS-Security。
WS-Security
由OASIS负责定义和维护的WS-Security概述了需要Web services解决的安全性的三个关键部分。特别是当请求和响应消息进行交换时,需要考虑以下三个方面:
- 消息完整性
- 消息机密性
- 身份验证
消息完整性保证消息来源是惟一的,在传输过程中不被篡改。这是通过外向SOAP消息签名实现的。签名典型地包含附加的数字证书(加密的纯文本 块),它表示一个惟一的消息散列。当收到消息时,接收方可将消息的内容与这个散列相比较。如果匹配,说明消息在传输过程中没有被篡改。
消息机密性保证只有接收方能够理解发来的消息。这是通过外向SOAP消息加密实现的。
身份验证保证只有通过身份验证的客户才允许调用Web Services。这是由客户端在服务调用中增加WS-Security 令牌 (例如,用户名/密码、X.509证书和Kerberos票据)实现 的。然后这个令牌在请求时经服务器的安全系统验证,只有确认合法,服务才会处理请求。
默认的SOAP规范本身不具有这些功能。虽然手工(通过编程)添加对这些特性的支持是可能的,但是这会耗费时间而且容易出错。幸而WS- Security规范描述了一个相应的实现,它利用了SOAP报头的固有可扩展性,几乎不用编码,就能够在Web Services消息交换中增加完整性、机密性和身份验证。
WebLogic Server 9.2的安全性配置概述
WebLogic Server 9.2完全支持WS-Security标准。也就是说对Web Services提供者和客户端的代码编写方式略加更改,即可实现消息的完整性、机密性和身份验证。
WebLogic Server API使得启用安全性十分容易,实现所有这三个安全性方面的基本步骤是:
- 编写和测试没有安全措施的服务。
- 为了完整性和机密性,为客户端和服务器设立一个keystore。
- 通过注释服务的源代码给服务增加安全性。
- 构建和部署受保护的服务。
Keystore实质上就是一个惟一、安全地标识服务器的证书集合。使用随JDK提供的keystore命令行工具能够创建keystore。使用WebLogic Server管理控制台可以将keystore导入WebLogic Server。
这三方面可以任意组合使用(例如,可以仅启用完整性、机密性和身份验证三者之一,也可以三者都启用)。本文将示范如何实现各方面。
策略和安全性概述
WebLogic Server 9.2使用策略文件维护Web Services的安全性。策略文件是一个XML文件,说明WebLogic Server怎样尝试启用安全性的各个方面。Web Services由策略文件包装,这些策略文件在部署过程中嵌入所生成的服务的WSDL文件之中。当客户端试图调用服务时,它应该首先获得该服务的含有策 略信息的WSDL文件。
BEA的策略文件
WebLogic Server安全性使用三个策略文件。
- Sign.xml——启用消息完整性所必需的。它包含配置信息,规定怎样在客户端和服务器之间进行消息签名。
- Encrypt.xml——启用消息机密性所必需的。它包含配置信息,规定怎样在客户端和服务器之间进行消息加密。
- Auth.xml——启用身份验证所必需的。它包含配置信息,规定怎样对客户端和/或服务器进行身份验证。
在部署过程中,这些策略文件必须再一次由Web Services包装。当然,只有所需的安全性方面的策略文件将被要求(例如,如果只要求消息的机密性,那么只需要包装Encrypt.xml,其余两个被忽略)。
创建WS-Policy文件
然后,我们关心的一个问题是如何创建这些策略文件。BEA提供了这些策略文件的文档和模式,可以用任何文本编辑器手工编写它们。不过,一个好消 息是 这些策略文件能够自动生成 。适当地注释源代码并运行jwsc Ant任务即可生成所需的sign.xml/encrypt.xml/auth.xml文件。随后,这些自动生成的文件将由可部署的Web Services自动包装。
通常,这些自动生成的策略文件足以满足要求。它们的内容将反映在初始源中的注释;那么,Web Services安全性的开发人员只需要考虑确保正确地注释源代码。开发人员不必关心策略文件的创建。
上面说过,有的时候,自动生成的策略文件可能是不可用的。可能需要对安全性框架进行一些额外的定制。比如说要求选择性地只加密消息的一部分而不 是全部,缺省情况下,自动生成的策略会加密整个消息。此时,开发人员可以自由地手工创建策略文件,然后注释源代码来使用手工创建的策略文件。这会阻止自动 文件生成。然而,一般不需要这样,因为自动生成的策略完全够用(并且只要极少的工作量)。
安全性注释
回想典型Web Services的开发,其中涉及到Java组件(例如,POJO或EJB)编码,然后 注释 产生Java Web Services(JWS)的代码。为了实现一个服务的安全性,要将@Policy和@Policy注释添加到JWS中。
例如,您可以将下面的注释添加到 JWS:
@Policies({ @Policy(uri="policy:Sign.xml"), @Policy(uri="policy:Encrypt.xml"), @Policy(uri="policy:Auth.xml") })
使用这些注释表示该Web Services需要所有三个方面:完整性、机密性和权限。当然,每个注释都有几个可添加的可选属性。稍后将介绍这些属性。
讲完了基础的知识,我们将进入一个实例,看看如何创建Web Services,并为之添加各安全性方面。
消息级安全教程
在本教程中,我们将创建一个简单的“Hello World”类型的服务,然后为之添加安全性方面。我们的 Web Services容器是WebLogic Server,开发环境是免费的开源WTP IDE。整个处理过程包括如下基本步骤:
- 配置WebLogic Server环境
- 配置WTP
- 激活TCP/IP监视器
- 构建、生成并部署一个简单的Hello World服务
- 为这个Hello World服务构建一个简单的客户端,并测试它
- 生成客户端密钥
- 将客户端证书导入服务器信任文件
- 为服务添加完整性
- 为服务添加机密性
- 为服务添加身份验证
其中某些步骤(例如,配置WebLogic Server环境)并非本文讨论重点,此处不再赘述;参考有关的BEA文档可获得关于如何实现这些步骤的更多信息。
配置WebLogic Server环境
如果没有安装 WebLogic Server 9.2,请先安装。使用BEA配置向导创建新的WebLogic域,管理用户名是weblogic,密码是password。无需特殊设置(例如,集群、 受管理的服务器、JDBC和JMS),所以可以跳过相关步骤。将该域命名为WSTestDomain,并将之留在默认的目录中。这就创建了域目录。如果您 使用的是Windows操作系统,则域目录应该类似于 C:beauser_projectsdomainsWSTestDomain。本教程中,此目 录简称为DOMAIN_DIR 。
配置WTP
就本教程而言,我们将采用广泛应用的开源Eclipse IDE,利用Web Tools Platform(WTP)插件。如果您还没有这些软件,请从这里下载 http://download.eclipse.org/webtools/downloads/。 注意,本教程假定读者熟悉 WTP/Eclipse。如果不是这样,建议读者先看一下Eclipse WTP的帮助文档。
这里使用WTP是随意的。您可以选择使用任何IDE(如若不然,还可采用一个基于文本编辑器和命令行的环境,虽然基于文本的环境不允许检查消息 流——为此需要一个额外的工具)。本文选择WTP的原因只是它得到了广泛应用,而且是开源的(即,可以免费下载和使用),还因为它支持TCP/IP监视器 功能,允许我们察看被发送的实际的受保护消息。
安装WTP通常包括获得包含该产品的ZIP文件,然后将它解压缩到文件系统里。之后,运行解压缩后的文件。出现提示后,选择新的workspace目录(如C:workspaces)。本教程中,这个目录简称为WORKSPACE_DIR 。
启动WTP之后,您需要将默认的JVM改换成WebLogic Server附带的JVM。切换到Java 透视图(除非它已经是当前活动的透视图)。在菜单中选择Window | Preferences 。在左边的窗格中展开Java ,然后在它下面选择Installed JREs 。我们需要添加BEA提供的JDK。在右边的窗格中,单击Add... 。再单击Browse... 按钮,然后找到您的BEA JDK的主目录(通常是C:beajdk150_04),单击OK 。如果出现提示要求您重建,则单击Yes 。
至此,配置完WTP,可以启动监视器了。
启动TCP/IP监视器
为了测试安全措施是否按要求工作,我们将启动WTP的TCP/IP监视器功能。这将允许我们截取和检查客户端与服务器间正在交换的消息。为此, 我们必须定义一个从 WTP内部指向WebLogic Server的服务器实例。首先,停止所有当前运行的WebLogic Server实例(使用 stopWebLogic.cmd 脚本)。
在WTP中,打开Servers视图。在视图任意位置右击,选择New | Server 。在弹出的菜单中,展开BEA Systems ,选择Generic BEA WebLogic Server v9.2 。单击Next 。在JRE下拉菜单中选择jdk150_04 ,然后单击Next 。
修改Domain Directory 指向DOMAIN_DIR 。修改Start Script 字段和Stop Script 字段,指向DOMAIN_DIR/bin 中的对应的启动/停止脚本(startWebLogic.cmd脚本和stopWebLogic.cmd脚本)。将Password 改成password,然后单击Finish 。回到Servers视图,在新出现的Generic BEA WebLogic Server v9.2 上右击,然后选择Monitoring | Properties 。此时会弹出Monitoring Ports窗口,单击Add... 。在弹出菜单上单击OK 。现在应该看到列出了一个新的监视器端口(7001/7002)。选择它,单击Start 。单击OK 。
此时,所有发往端口7002的业务都将传递给监视器,在转发给(正确的)服务器端口 7001之前由显示器显示出来,以便我们检查传入和发出的流量。
构建、生成和部署一个简单的Hello World服务
现在我们要创建一个基本的 Web Services JWS。它是一个非常简单的服务。传入一个字符串,它就会返回适当的问候。下面来构建和部署这个服务。
在WTP中创建一个名为WSTest 的新Java项目。在这个项目中创建一个名为com.test.HelloWorldService的新Java类。
现在我们要给项目添加BEA weblogic.jar 库,以便我们的代码可以正确的编译。右键单击WSTest 项目,选择Properties 。出现 Properties 窗口。单击左边窗格中的Java Build Path 。单击右边窗格中的Libraries 。单击Add External JARs 。在出现的JAR Selection窗口中找到您的WebLogic Server库文件夹,选择weblogic.jar (通常类似于C:beaweblogic92serverlibweblogic.jar)。单击Open 。现在,应该会看到weblogic.jar 列于Libraries中。单击OK 。
如下设置HelloWorldService.java的源:
package com.test; import javax.jws.*; @WebService(name = "HelloWorldPortType", serviceName = "HelloWorldService", targetNamespace = "http://mycompany.com") public class HelloWorldService { public String sayHello(String name) { return "Hello there, " + name; } }
注意@WebService注释的使用,它将这个类定义为一个Web Services。还要注意一个sayHello业务方法,它捕获一个String作为参数,并返回一条相应的问候语。
下一步是创建用于构建和部署服务的Ant脚本。在项目目录(WORKSPACE_DIR/WSTest )中创建一个名为build.xml 的文本文件,然后建立它的内容,如下:
package com.test; <project default="build"> <taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" /> <target name="jwsc"> <jwsc srcdir="." destdir="." > <jws file="com/test/HelloWorldService.java" /> </jwsc> </target> <target name="build" depends="jwsc"> <wldeploy action="deploy" name="HelloWorldService" source="com/test/HelloWorldService.war" user="weblogic" password="password" adminurl="t3://localhost:7001/" targets="AdminServer"/> </target> </project>
这里没什么特别值得注意的内容。定义了两个target——一个建立实际的服务,一个部署这个服务。
现在可以运行这个服务了。在WSTestDomain中启动管理服务器。(在WTP内的Servers 视图中右击Generic BEA WebLogic Server v9.2 ,然后单击Start 。)打开命令shell窗口,执行DOMAIN_DIR/bin 中的setDomainEnv脚本。然后,还在这个命令shell窗口,进入WORKSPACE_DIR/WSTest 目录,运行ant命令。
脚本应该运行了,您应该看到一条BUILD SUCCESSFUL消息。不要关闭命令shell窗口,后面还需要它。这里,服务应该被构建、部署并运行。打开浏 http://localhost:7001/HelloWorldService/HelloWorldService?WSDL,应该会看到这个服务 的WSDL文件。将其加入书签,因为本教程始终都需要它来生成客户代理。现在,在WORKSPACE_DIR/WSTest 目录下保存这个文件为HelloWorldService.wsdl(确保文件名后面不要加上“.xml”后缀)。
为HelloWorld服务构建一个简单的客户端并进行测试
我们现在要构建一个简单的Java客户端来测试前面创建的服务。尽管能够用WebLogic Server 控制台工具测试这个服务,但最终还是要用客户端来测试其各安全性方面。
回想一下,客户端要成功地调用服务,首先必须生成客户端代理。这可通过另一个Ant脚本来完成。在WORKSPACE_DIR/WSTest 文件夹中创建一个名为gen-client.xml的新文本文件,并且加入下面的内容:
package com.test; <project default="build-client"> <taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask"/> <target name="build-client"> <clientgen wsdl="HelloWorldService.wsdl" destDir="." packageName="com.test.client"/> </target> </project>
从前面打开的命令shell窗口运行ant -buildfile gen-client.xml命令。您应该会看到一条BUILD SUCCESSFUL消息。这就生成了客户端代理。
回到WTP,刷新WSTest项目,应该能看到新生成的com.test.client包。然而,WTP会报告新生成的代理存在一个错误。要修 正它,就要为项目添加webserviceclient.jar库,添加方法与添加weblogic.jar相同 (webserviceclient.jar与weblogic.jar位于同一目录)。现在就可以开始编写客户端的代码了。
在WTP内的WSTest项目中创建名为com.test.client.HelloWorldClient的新java类,如下设置它的源:
package com.test; import com.test.client.*; public class HelloWorldClient { public static void main(String[] args) throws Throwable { com.test.HelloWorldService service = new HelloWorldService_Impl(); HelloWorldPortType port = service.getHelloWorldPortTypeSoapPort(); String greeting = port.sayHello("Gary"); System.out.println("The greeting returned was: " + greeting); } }
这个客户端非常简单,仅使用客户代理类以获得到服务的引用,然后调用其sayHello方法。
运行这段代码,会出现适当的控制台打印结果。
返回的问候是:Hello there, Gary
请注意,机关我们已经激活了TCP/IP监视器,但这个测试还不会用到它。这是因为客户端在端口7001直接找到服务器,而不是通过监视器端口7002。我们稍后将介绍怎样修改它。
现在已经构建了非常简单的Web Services和客户端,但还不具有安全性机制。下面将加以介绍。
生成客户端密钥
我们需要一组密钥来实现各种形式的消息完整性(和加密)。密钥构成证书的基础,证书用来惟一地对一条消息进行签名以保证消息的完整性。发送者可以在消息中附加自己的证书;接收者可以检查证书,核对发送者身份,确定消息在传输中未被篡改。
客户端也需要随证书发送数字签名增加消息完整性。单独的证书本身是没有意义的。客户端获得消息的散列,然后用专用密钥加密它,从而生成数字签 名。然后,服务器使用消息中附加的客户证书(即,公用密钥)解密这个散列,证明它来自客户端。下一步,对比解密的散列和得到的消息散列。如果二者等同,则 证明消息未被篡改。本教程有两个通信方:WebLogic Server和客户端。双方都需要密钥。
WebLogic Server有自己的示范用的“dummy”密钥,虽然不能用于生产,但是本教程用其进行示范就足够了。这里我们将使用这些dummy密钥,但请记住,在实际环境中应该使用新生成的密钥。我们马上要用到keytool命令为客户端和服务器创建密钥。
现在来创建客户端密钥。具体来说,我们将创建一对客户端密钥(公钥和相关联的私钥)。这对密钥中的私钥将用作消息的解密和数字签名。密钥对保存 在keystore文件里。Keystore随密钥对的创建而创建。如果已经存在指定的keystore,则只需要将新的密钥对加进去。公钥在X.509 证书 内。证书和私钥保存在keystore中,用一个别名来识别。
打开一个新的命令shell,进入BEA JRE bin目录(通常类似于C:beajdk150_04jrebin)。然后键入下面的命令:
keytool -genkey -keyalg RSA -keystore C:client_keystore.jks -storepass abc123 -alias client_key -keypass client_key_password -dname "CN=Client, OU=WEB AGE, C=US" -keysize 1024 -validity 1460
(此命令将在根目录下创建keystore。根据需要,可以改变它的位置。如果您使用的是基于Unix的操作系统,可以用更标准的Unix命名文件系统规则代替“C:”。)
创建的keystore名称是C:client_keystore.jks,访问密码是abc123。密钥对的别名是client_key,私 钥的保护密码是client_key_password。创建密钥对的算法是RSA。与别名client_key相关联的特殊命名是CN=Client、 OU=WEB AG和C=US,在证书中用作发证者和主题域。密钥长度为1024 位(BEA要求的最小长度)。最后,对应的证书有效期为1460天(4年)。成功的话,C:下应该出现一个名为client_keystore.jks的 新文件。这就是客户端要用到的keystore。
现在,我们将要检验这些密钥是否正确地创建了。在命令提示符窗口键入:
keytool -list -keystore C:client_keystore.jks -storepass abc123 -v | findstr Alias
这时应显示:
Alias name: client_key
Keystore已经成功地创建了。客户端keystore包含一个名为client_key的实体的私钥和一个公钥(也称证书)。数字签名和加密都需要它们。
请勿关闭第二个命令shell窗口。稍后还要使用它。
将客户端证书导入服务器信任文件
现在必须要告诉服务器信任客户端的证书。
WebLogic Server维护着一个信任文件,实质上就是它要信任和接受的证书列表。遗憾的是,我们前面生成的客户端密钥不在信任文件里。这意味着我们的客户端证书如果被WebLogic收到,会被立刻拒绝。我们需要做的是将客户端证书导入服务器信任文件。
这个过程分两个阶段:首先,必须从客户端的keystore导出证书,然后将其导入服务器信任文件。当前配置的服务器使用一个“demo”信任文件(Demotrust.jks),它又引用标准JDK信任文件。标准JDK信任文件一般位于:
C:beajdk150_04jrelibsecuritycacerts。(注意,根据您的操作系统和安装设定不同,这个目录可能会有不同。)
我们需要将客户端证书导入这个cacerts文件。
首先,从client_keystore.jks导出客户端证书。在生成密钥时打开的命令shell窗口中,键入以下命令:
keytool -export -alias client_key -file client_cert.der -keystore C:client_keystore.jks -storepass abc123
第二步,将证书导入服务器信任文件。键入以下命令:
keytool -import -alias client_key -file client_cert.der -keystore C:beaJDK150~1jrelibsecuritycacerts
(如果您的cacerts文件不是位于C:beaJDK150~1jrelibsecurity,那么请相应地修改命令。)
出现提示后键入密码changeit。(changeit是WebLogic Server附带的默认密码。当然,在生产中应当换成更安全的密码。)
接着会出现提示this certificate [no]:。键入 y,按回车。
如果一切顺利,您将看到Certificate was added to keystore消息。
此时,客户端的证书已经加入服务器信任文件。现在服务器会信任使用这一证书的任何客户端。
关闭运行keytool命令的命令shell窗口。
为服务加入完整性
既然有了客户端密钥,现在来看看它将如何帮助我们实现消息完整性。如果一方发送SOAP消息并在外发消息中附加证书,则接收方能够阅读证书,确 信地识别发送者,确保消息在传输中未被篡改。这是通过客户端随SOAP请求发送自己的证书实现的。(回想一下,发出的证书也有一个消息的散列摘要。被篡改 后,消息的散列将有所是不同的,服务器能检测出来。这就保证了消息的完整性。)
为了利于它实现,我们必须进行两项修改:
- 必须编辑服务类,以便请求签名。
- 必须编辑客户类,以便在请求中附加签名。
使服务请求消息完整性非常简单,只需要向源代码添加一个单独的注释。切换回WTP,打开HelloWorldService.java。添加下面突出显示 的代码:
import javax.jws.WebService; import weblogic.jws.Policies; import weblogic.jws.Policy; @WebService(name = "HelloWorldPortType", serviceName = "HelloWorldService", targetNamespace = "http://mycompany.com") @Policies({ @Policy(uri="policy:Sign.xml") }) public class HelloWorldService { public String sayHello(String name) { return "Hello there, " + name; } }
我们所作的一切就是加入了一个单独的注释(@Policies/@Policy)并导入了所需的适当的包。这个注释将确保生成的Web Services总是要求客户端对其SOAP请求进行签名。保存所做的修改。这部分应该不会出现错误。
现在需要重新生成服务。使用前面生成服务而打开的命令窗口,运行ant命令。您将看到BUILD SUCCESSFUL消息;服务应该被生成、打包和部署了。
由于修改了服务,我们还要基于新生成的WSDL文件重新生成客户代理。回到浏览器,再次打开WSDL文件的URL。将它保存为 WORKSPACE_DIRWSTestHelloWorldService.wsdl。用文本编辑器检查这个文件。注意,那里现在有一个名为 wssp:Integrity的元素,它包含了相当多的信息,其中有它信任的内容。如果您遍历wssp:TokenIssuer元素体,应该看见一个到 CN=Client,OU=WEB AGE, C=US的引用,它确实是我们的客户端密钥中生成的,之后导入WebLogic Server信任文件的信息。还请注意WSDL文件包括的新的Sign.xml策略:
<wsp:Policy s0:Id="Sign.xml"> ... </wsp:Policy> ... <portType name="HelloWorldPortType" wsp:PolicyURIs="#Sign.xml"> .. </portType>
WSDL文件末尾处有如下代码:
<s2:address location="http://localhost:7001 /HelloWorldService/HelloWorldService"/>
如下将端口号改为7002:
<s2:address location="http://localhost:7002 /HelloWorldService/HelloWorldService"/>
为何要这样做?原因很简单。我们希望客户端请求找到端口7002——监视器端口。保存并关闭WSDL文件。
从命令shell窗口运行ant -buildfile gen-client.xml命令。您应该看到熟悉的BUILD SUCCESSFUL消息。现在重新生成了客户代理。
回到WTP中,刷新WSTest 项目。再次运行HelloWorldClient类。发生了什么?一个异常。检查出现的堆栈跟踪,找到Failed to add Signature消息。这说明服务要求证书,但是客户端没有附上。我们要修改客户端代码,以便调用服务时确实能够附上证书。
打开WTP中的HelloWorldClient.java。添加下列import语句。
import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.xml.rpc.Stub; import weblogic.security.SSL.TrustManager; import weblogic.wsee.security.bst.ClientBSTCredentialProvider; import weblogic.wsee.security.unt.ClientUNTCredentialProvider; import weblogic.xml.crypto.wss.WSSecurityContext; import weblogic.xml.crypto.wss.provider.CredentialProvider;
现在,向main方法添加以下突出显示 的代码。
public static void main(String[] args) throws Throwable { com.test.client.HelloWorldService service = new HelloWorldService_Impl(); HelloWorldPortType port = service.getHelloWorldPortTypeSoapPort(); List credProviders = new ArrayList(); CredentialProvider cp = new ClientBSTCredentialProvider( "C:client_keystore.jks", "abc123", "client_key", "client_key_password"); credProviders.add(cp); Stub stub = (Stub) port; stub._setProperty( WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders); stub._setProperty( WSSecurityContext.TRUST_MANAGER, new TrustManager() { public boolean certificateCallback(X509Certificate[] chain, int validateErr) { // Put some custom validation code in here. // Just return true for now return true; } }); String greeting = port.sayHello("Gary"); System.out.println("The greeting returned was: " + greeting); }
保存代码。这里应该不会出现错误。现在运行更新的HelloWorldClient类。控制台应该返回与之前一样的信息,表明服务工作正常。然而,在后台还发生了一些别的事。回到WTP,应该看到TCP/IP Monitor 视图。单击它,更改Request 和Response 窗格来显示XML。
检查Request窗格的内容,它将客户端发送的信息表示成外发SOAP请求消息。注意,它已经附加了一个含有客户证书 (dsig:KeyInfo元素引用的wsse:BinarySecurityToken)、实际的SOAP体(dsig:DigestValue)的单 向散列(也称报文摘译)和数字签名(dsig:Signature)的安全报头(wsse:Security)。消息已经签名了。您会注意到一个消息的摘 要(dsig:DigestValue),它是实际的SOAP体的加密的单向散列。
同样地,检查Response窗格。注意服务器返回的消息也附加了证书;这是服务器证书。为何要这样做?当注释服务类时,您指定了Sign.xml策略,默认规定传入和外发的签名——所以客户端和服务器的签名交换。
既然已经交换了签名,那么任一方都能够验证消息确实来自指定的发送者,并且没有被篡改(通过检查摘要)。我们已经实现了 消息的完整性 。 然而,请注意,消息的soapenv:body依旧是纯文本;没有消息的机密性(加密)。您能够清楚地看到SOAP 请求中的<name>元素和SOAP响应中的<return>元素。
为服务加入机密性
现在我们要为服务加入机密性。这意味着希望在客户端和服务器之间加密消息(SOAP体)。其基本过程与添加消息的完整性一样:注释并重新生成服务,然后更新客户端。
打开WTP中的HelloWorldService.java。添加下面突出显示 的注释:
@Policies({ @Policy(uri="policy:Sign.xml"), @Policy(uri="policy:Encrypt.xml" ) })
(别忘了在Sign.xml注释后添加逗号。)
这个注释指定我们希望客户端和服务器使用加密。默认加密是双向的(即,从客户端到服务器、从服务器到客户端两个方向)。如果只要求单向加密,可向注释添加可选的direction属性来处理这一问题。
现在需要重建服务。从命令窗口运行ant命令。如前,您将看到BUILD SUCCESSFUL消息。
现在,更新客户端。首先,像以前那样获得WSDL文件并保存。用编辑器打开它。您将注意到一个新的元素:wssp:Confidentiality。这示意客户端使用加密。还请注意如下所示的Encypt.xml策略的内容:
<wsp:Policy s0:Id="Encrypt.xml"> ... </wsp:Policy> ... <portType name="HelloWorldPortType" wsp:PolicyURIs="#Sign.xml #Encrypt.xml"> .. </portType>
由于新的部署重新生成了WSDL文件,我们需要再为监视器更新端口号。WSDL文件末尾处有如下代码:
<s2:address location="http://localhost:7001 /HelloWorldService/HelloWorldService"/>
如下所示将端口号改为7002:
<s2:address location="http://localhost:7002 /HelloWorldService/HelloWorldService"/>
保存并关闭WSDL文件。现在,从命令shell窗口运行ant -buildfile gen-client.xml命令,您会看到BUILD SUCCESSFUL消息,这时客户代理已经更新了。
下面还要做什么呢?实际上不需要任何改动了。客户端无需添加任何代码使消息加密。客户端代理将提供所有的加密工作。这是使用Web services安全机制的一个主要优点;开发人员编写任何加密代码!
运行HelloWorldClient,您将看到正常的问候响应。有什么改变了?初看起来似乎并无变化。然而,检查TCP/IP监视器,您将看 到请求和响应已经加密了;无法像先前那样找到<name>元素。这里有<CipherData>元素和一些加密的文本。注意,只 是加密了消息体(请求的name元素和响应的return元素);所有的消息报头没有加密。还请注意,安全报头(wsse:Security)已经添加了 ns1:EncryptedKey元素。
消息机密性已经被加入服务了!
为服务添加身份验证
接着我们可以向Web Services添加授权机制。简单地说,我们可以强制客户端随SOAP请求提供用户名和密码;如果WebLogic Server的用户注册库没有这个用户名和密码,则服务器将拒绝对服务的访问。这允许一种形式的访问控制。注意这与消息的完整性中的身份识别不同。消息的 完整性通过证书进行客户识别;权限涉及客户端是否实际有权调用服务。如果客户端未能成功地通过WebLogic Server的用户注册库身份验证却试图调用服务,则服务器将拒绝对服务的访问。
下面我们要为WebLogic Server的用户注册库加入一个用户,然后修改服务强制客户端进行身份验证。然后我们将使用客户端进行测试。
第一步是在WebLogic Server的用户注册库中创建一个用户。用户注册库默认嵌入在WebLogic Server的LDAP服务器中,通过WebLogic Server管理平台,可以加入用户。确定服务器在运行,然后使用浏览器浏览 http://localhost:7001/console。使用用户名weblogic和密码password登录,此时将打开管理平台。
在左边的Domain Structure窗格单击Security Realms 。在右窗格中,单击myrealm 。Myrealm 显示当前WebLogic Server的安全配置。我们将向这个安全配置添加一个测试用户。单击Users and Groups 标签。单击New 按钮。
在Name 字段中键入suzie。在Description 字段中键入An authenticated Web service user。在Password 和Confirm Password 字段中键入OK 。
我们已经在WebLogic Server的用户注册库中创建了一个新用户。现在可以编辑服务,要求所有客户端给出用户名/密码(希望与注册库中的用户匹配)进行身份验证。打开WTP中的HelloWorldService.java,然后加入下面突出显示 的部分。
@Policies({ @Policy(uri="policy:Sign.xml"), @Policy(uri="policy:Encrypt.xml"), @Policy(uri="policy:Auth.xml" ,direction=Policy.Direction.inbound) })
新的注释指定强制实施授权策略,但只针对入站流量。(本例中,强制服务器对于客户端进行反向身份验证意义不大。)
保存文件。应该不会出现错误。现在可以构建并部署服务了。从命令shell窗口运行ant命令。如前,将会看到BUILD SUCCESSFUL消息。
既然已经重新生成服务,则必须像前面所做的那样重新生成客户端代理。像前面所做的那样获得并保存WSDL文件。用编辑器打开,将出现一个新的元 素wssp:Identity。它示意客户端在调用服务时应该发送用户名和密码。另请注意如下所示的新Auth.xml策略的内容:
<wsp:Policy s0:Id="Auth.xml"> ... </wsp:Policy> ... <input> <s2:body parts="parameters" use="literal"/> <wsp:Policy> <wsp:PolicyReference URI="#Auth.xml"/> </wsp:Policy> </input>
如前,由于新的部署重新生成了WSDL文件,我们需要更新监视器端口号。WSDL文件末尾处有如下代码:
<s2:address location="http://localhost:7001/HelloWorldService/HelloWorldService"/>
如下所示,修改端口号为7002:
<s2:address location="http://localhost:7002 /HelloWorldService/HelloWorldService"/>
保存并关闭WSDL文件。现在,从命令shell窗口运行ant -buildfile gen-client.xml命令,会看到BUILD SUCCESSFUL消息。客户端代理已经更新了。
回到WTP,刷新WSTest 项目。运行HelloWorldClient类。会发生什么呢?
javax.xml.rpc.soap.SOAPFaultException: Unable to add security token for identity
客户端试图调用服务,但又不提供任何授权凭证。客户端代码需要加以修改,以便使用刚才创建的用户名/密码suzie/munchkin来调用服务。现在开始向HelloWorldClient.java的main方法添加下面突出显示 的代码:
stub._setProperty( WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders); String username = "suzie"; String password = "munchkin"; cp = new ClientUNTCredentialProvider(username.getBytes(), password.getBytes()); credProviders.add(cp); stub._setProperty(
运行代码,会返回正常的问候消息。这样,我们就知道了客户端调用服务前被强制添加凭证。查看监视器,检查请求,应该看到一个新的部分:
<wsse:UsernameToken> <wsse:Username>suzie</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/ oasis-200401-wss-username-token-profile-1.0#PasswordText">munchkin</wsse:Password> </wsse:UsernameToken>
这些的确是我们提供的凭证。注意,这些凭证以纯文本发送。WS-Security规范没有涉及用户凭证加密;而是推荐采用传输层安全措施(即,保护整个TCP/IP套接字)。
身份验证已经成功地加入Web Services了!
展望未来:WebLogic Server 10的安全性配置
WebLogic Server 10最近已发布。对于现有的受保护的Web services,这意味着什么呢?幸运的是,变化不是很多。第十版中服务的部署和运行没有变化。然而,客户端代码需要使用第十版的客户API重新生成。 此外,WebLogic Server 10加入了WS-SecurityPolicy 1.2支持,现在它支持WS-Security 1.1。(WebLogic Server 9.2支持WS-Security 1.0。)
WS-SecurityPolicy 1.2的重要性在于可以创建与BEA专有安全策略文件相对的“标准”安全策略文件。WS-SecurityPolicy规范发布之前发布的 WebLogic Server 9.2使用的是依据采用专有BEA安全策略模式的旧版WS-Policy规范写成的安全策略文件。
应该采用哪一种策略文件?BEA建议采用WS-SecurityPolicy标准策略文件代替其专有策略文件。实际上,这两种策略文件第十版都支持,但这二者是不兼容的,所以一个给定的Web Services只能采用二者之一。
可是在您急着将WebLogic Server 9.2策略文件迁移到新标准之前,谨记WS-SecurityPolicy尚有局限之处,因为在BEA实现它的时候,它还只是(依然是)一个草案。具体来 说,如果您需要元素级的数字签名和/或加密,或者要求SAML 1.1,那么您仍然必须采用专有的BEA WebLogic 9.2型策略。
根据WS-Security,即使WebLogic Server 10支持WS-Security 1.1,BEA仍然推荐为了互操作性使用WS-Security 1.0策略。只是当您要求更强的安全性时,才应该采用WS-Security 1.1策略。而且只有使用新的WS-SecurityPolicy 1.2策略文件,WS-Security 1.1才被支持。
结束语
在本文中,我们讨论了Web services安全性的三个方面:消息的完整性、机密性和身份验证。我们已经看到编写含有这三个方面的“安全”Web Services非常简单;所要做的只是用适当的注释来注释Web Services代码。我们了解了使用什么注释来实现每个方面,弄清了必须如何修改客户端代码调用受保护的服务,看到了SOAP消息自身如何改变以反映新 加入的安全性。在教程中,我们建立了一个Web Services,并逐步加入所有三个方面。
由于SOAP消息的“纯文本”的性质,当我们部署Web services作为企业生产环境的一部分的时候,强大的安全性是非常重要的。WS-Security与WebLogic Server的结合为这个问题提供了一个极好的解决方案,使开发人员得以轻松地部署和维护企业服务。
发表评论
-
字符串分割--java中String.split()用法
2013-03-06 14:25 74151在java.lang包中有String.sp ... -
用 HttpServletResponseWrapper 实现 Etag 过滤器
2012-07-09 16:58 3759原文出处:http://blog.chenlb.com/200 ... -
Fitnesse使用
2012-05-05 13:27 23494Fitnesse 的使用 一,介绍 Fitnesse是一种 ... -
Customizing the new FitNesse parser
2012-05-05 13:13 2134FitNesse began its life using ... -
java application中内嵌ActiveX控件
2011-11-14 15:57 5524我这里用的是SWT/JFace开发application,SW ... -
Google Java Developer Tools Downloads
2011-08-09 00:04 2347WindowBuilder Pro原来叫WindowB ... -
Jalita
2011-08-06 00:49 1566Jalita (Java light terminal ada ... -
【转】用Java写字符终端界面
2011-07-29 13:13 2122终端界面GUI开源项目charva。 这个框架让你可以用开发 ... -
[转]mybatis下的分页,支持所有的数据库
2011-07-21 13:21 14841大 家都知道,mybatis的自带分页方法只是逻 ... -
Java framework for text- & console-based forms?
2011-07-21 01:06 1711charva jcurses JNA , ... -
JNA(Java Native Access)学习入门
2011-07-21 01:04 22627Java Native Access 项目 在 ... -
JAVA上加密算法的实现用例
2011-06-25 12:38 4884来源:www.ibm.com ... -
如何将GlassFish作为Windows服务运行
2011-05-18 23:21 2375本文档来自GlassFish官方网站,详细介绍了将 G ... -
JAVA UDP打洞必备知识点---NAT
2011-05-05 12:56 8699一、引言 RFCl631 ... -
Keystore概念,Keytool工具使用
2011-04-28 16:20 2906近来由于项目需要做Single Sign On, 研究了一 ... -
利用Eclipse Profile Plugin监控分析Tomcat性能
2011-04-18 16:14 3703目前新版本的Eclipse在启动应用服务器的时候有一个新的选 ... -
m2eclipse: Eclipse is running in a JRE, but a JDK is required
2011-02-04 23:43 2542Eclipse 安装了Maven插件,启动Eclipse ... -
利用JNative实现Java调用动态库
2010-10-18 00:43 2101由于项目要求,需要用J ... -
RHEL5支持大内存
2010-10-08 16:19 3005安装 RHEL 5 ,硬件为 4G 内存,安装完成 ... -
Windows Server 2003 和 Windows 2000 提供大内存支持
2010-10-08 16:19 1854本文介绍物理地址扩展 ...
相关推荐
WebLogic Server 9.2 环境部署详解 WebLogic Server 是一款由 Oracle 公司提供的企业级 Java 应用服务器,它提供了一个用于开发、集成、部署和管理Java EE应用程序的平台。本篇文章将详细阐述如何在Windows环境下...
### MyEclipse 7 在 WebLogic 9.2 上开发 Web Service 范例 #### 环境说明 在本教程中,我们将使用 MyEclipse 7 和 WebLogic 9.2 开发一个简单的 Web Service。为了进行这项工作,需要确保已经正确安装并配置了...
WebLogic 9.2 安装及配置 WebLogic 9.2 是 BEA Systems 公司开发的一款 Java EE 应用服务器,用于部署和管理 Java EE 应用程序。本文档将指导读者安装和配置 WebLogic 9.2 服务器,解决常见的安装和配置问题。 一...
WebLogic Server 9.2 是一款由甲骨文公司(Oracle)提供的企业级Java应用程序服务器,用于部署和管理Java EE应用程序。在这个版本中,安装过程是初步接触WebLogic Server的关键步骤,接着是配置数据源和Web应用,...
9. 运行开始 -> 程序 -> BEA Products -> User Projects -> mydomain -> Start Admin Server for WeblogicServer Domain,检查服务器是否启动成功。 在配置 MyEclipse 的 WebLogic 9 服务器启动时,需要打开首选项...
4. **部署应用**:通过菜单“Server -> New Server”选择WebLogic 9.2服务器并进行应用部署。 #### 六、总结 本文档详细介绍了如何在MyEclipse 5.0环境中配置WebLogic 9.2服务器的过程,包括选择WebLogic 9.2的...
WebLogic 9.2配置JMS(Java Message Service)涉及一系列步骤,主要目的是为了实现分布式消息传递,包括点对点的Queue模式和发布/订阅的Topic模式。在本例中,我们将专注于配置发布/订阅模式,即Topic。以下是详细的...
配置完成后,你就可以在MyEclipse中创建和部署J2EE 1.4标准的项目到WebLogic 9.2服务器上了。在开发过程中,记得检查项目的JDK版本和Servlet规范,以确保与WebLogic服务器的兼容性。同时,适时更新服务器和开发环境...
在本文中,我们将深入探讨如何在MyEclipse集成开发环境中配置WebLogic服务器,特别是WebLogic 9.2版本。WebLogic是由BEA Systems(现已被Oracle收购)开发的一款企业级应用服务器,它支持J2EE标准,提供了一个用于...
WebLogic Server是Oracle公司提供的一款企业级应用服务器,它基于Java EE标准,支持多种开发框架和技术栈,如EJB、JSP/Servlet、JMS、Web Services等。作为一款高性能且稳定的应用服务器,WebLogic被广泛应用于各种...
- **文档范围及受众**:本文档旨在为使用 BEA WebLogic Server 版本 9.2 的开发者提供关于 Web 服务开发的指导。适用于希望了解如何在 WebLogic 平台上构建、部署和管理 Web 服务的应用程序开发人员。 - **文档指南*...
通过以上步骤,我们可以顺利地在MyEclipse中配置WebLogic 9.2服务器,实现Java Web项目的开发与部署。这一过程解决了因J2EE规范差异和JDK版本不兼容所带来的问题,为开发者提供了一个稳定高效的开发环境。希望本文能...
如果在MyEclipse中创建的项目选择了J2EE 1.4或更高的标准,则在部署到WebLogic 8时会出现错误,提示web.xml部署描述符不合规。 - **解决方案**:为了解决上述兼容性问题,可以选择升级WebLogic到9.2版本,该版本支持...
- 通过 `开始` 菜单找到 `BEA Products` -> `User Projects` -> `mydomain` -> `Start Admin Server for WeblogicServer Domain`。 - 检查服务器是否已成功启动。 #### 在 MyEclipse 中配置 WebLogic 9 服务器 ...
最后,在“Paths”下的“Prepend to classpath”列表框中,通过“Add JAR/ZIP”添加必要的库文件,如weblogic.jar、webservices.jar以及数据库驱动(例如WebLogic自带的SQL Server驱动mssqlserver4v65.jar)。...
2、安装SQL Server 2000、打上补丁Sp4 安装好SQL Server 2000后注意启动SQLServer服务器 3、安装QC9.0 服务器名称也可以是IP地址 4、启动QC9.0 ...
2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)...
2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)...
9.2 Managing Events and Resources with Liferay’s Calendar Portlet . . . . . 211 9.3 Discuss, Ask, and Answer Using the Message Boards . . . . . . . . . . . 221 9.4 Working together with the Wiki . . ...