Java Web 服务 Axis2 WS-Security基础
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java Web 服务: Axis2 WS-Security基础
本文来自编程入门网:/Programming/Java/201110/30204.htm
简介:了解如何将Rampart 安全模块添加到Apache Axis2 并开始在Web 服务中使用WS-Security 特性。
安全性对于众多企业服务来说都是一个重要需求。
并且,尝试实现自己的安全性也颇具风险,因为任何微小的疏忽都会导致严重的安全漏洞。
这些特征引起了人们对安全处理标准化的兴趣,许多专家为标准作出贡献并避免出现任何个人的疏漏。
基于SOAP 的Web 服务可以使用广泛支持的WS-Security 和相关标准来满足它们的安全需求,允许针对每种服务相应地配置安全性。
Apache Axis2 通过Rampart 模块支持这些安全标准(见参考资料)。
在本文中,您将看到如何为Axis2 安装、配置和使用Rampart 以实现基本的安全功能,即在一个服务请求中发送用户名和密码。
在本系列的后续文章中,您将理解如何使用Rampart 实现更加复杂的安全性。
WS-Security
WS-Security 是向SOAP Web 服务消息交换添加安全性的一种标准(见参考资料)。
它使用一个SOAP 消息头部元素将安全信息附加到消息中,使用令牌(token)的形式传递不同类型的声明(包括名称、身份、密匙、组、特权、功能等等)以及加密和数字签名信息。
WS-Security 支持多种形式的令牌、多个可信任域、多种签名格式和多种加密技术,因此大多数情况下头部信息需要针对每种内容包含特定的格式和算法识别。
附加的信息会导致头部信息产生复杂的结构,如清单1 所示(进行了大量编辑)—包含签名和加密的样例消息:
清单1. 包含签名和加密的样例消息
将更进一步,探讨清单1 所示的复杂结构类型。
WS-Security 应用于实际的SOAP 消息交换。
服务实现可以检验WS-Security 是否恰当应用于传入的消息,但是客户机需要提前知道它们必须实现什么才能使用服务。
由于WS-Security 的复杂性以及所支持的选项有限,因此仅使用文本描述很难实现这个目的,而手动配置WS-Security 处理极容易出现错误。
WS-Policy 是一个用于为Web 服务指定扩展需求的通用结构,而WS-SecurityPolicy 是一个专门针对WS-Security 支持的WS-Policy 扩展。
这两者合起来可以以机器可读的方式描述WS-Security 需求。
WS-Policy 和WS-SecurityPolicy 信息可以单独使用,也可以直接嵌入到Web Services Description Language (WSDL) 文档内部,这样Web 服务框架就可以将它们自动配置为服务的需求。
Rampart 简介
Rampart 是Axis2 的安全模块,支持WS-Security、WS-SecurityPolicy、WS-SecureConversation 和WS-Trust。
在本文中,您将只查看Rampart 的WS-Security 和WS-SecurityPolicy 功能;后续文章将讨论其他特性。
由于Rampart 是以模块形式实现(实际上是一对模块— rampart.mar 和rahas.mar),它将插入到Axis2 处理框架中并在出站和入站处理的特定点拦截消息,检查对消息的修改或根据需要对消息作出修改,从而完成工作。
安装Rampart
Rampart 附带了一些.jar 文件(在发行版的lib 目录中),以及一对.mar 模块文件(位于dist 目录中)。
您必须将.jar 文件添加到类路径中才能对Axis2 使用Rampart,并且必须将.mar 文件添加到类路径或Axis2 库结构中。
处理Rampart .jar 和.mar 文件的最简单方法是将它们添加到Axis2 安装中。
可以从Rampart lib 目录中直接将.jar 文件复制到Axis2 lib 目录,从Rampart dist 目录中直接将.mar 文件复制到Axis2 库/模块目录中。
(还可以使用Ant build.xml 在Rampart 样例目录中将文件复制给Axis2 安装。
只需要将AXIS2_HOME 环境变量设置为Axis2 安装目录并从打开Rampart 样例目录的控制台运行ant )。
对于众多WS-Security 特性,您还需要向JVM 安全配置添加Bouncy Castle 安全提供程序,向Axis2 安装添加Bouncy Castle .jar。
本系列后续文章中涉及的其他安全特性(不包括本文将介绍的UsernameToken)需要使用这一步骤。
由于某些安全算法涉及专利问题,Bouncy Castle .jar 可以从Rampart 独立下载(见参考资料)。
为您的Java 运行时下载合适的.jar 版本,并向Axis2 lib 目录添加.jar。
您随后需要修改Java 安装的安全策略来使用Bouncy Castle 代码,需要向Java 运行时的lib/security 目录中的java.security 文件添加一行代码。
查找文件中具有不同security.provider 行的部分,然后添加以下代码行:
序的代码行的后面。
要在Axis2 服务器安装中使用Rampart 代码,需要创建一个新的axis2.war 文件,其中包括新添加的Rampart .jar 和.mar 文件。
可以使用webapp 目录中提供的Ant build.xml 来创建axis2.war,假设您做了一处修改:删除文件末尾的<exclude name="axis2-codegen*.jar"/> 行。
然后在控制台中打开Axis2 webapp 目录并运行ant。
运行完build.xml 后,会发现创建的axis2.war Web 应用程序出现在Axis2 安装的dist 目录中。
样例应用程序
示例代码中提供的应用程序(见下载)基于我在“Axis2 数据绑定”中用于演示Axis2 数据绑定方法的示例。
对于本文以及有关Axis2 WS-Security 支持的后续文章,我将这个示例精简到三个操作:getBook、addBook 和getBooksByType。
为了保持简单性,只提供了Axis Data Binding (ADB) 版本的代码,但是这并不是在Axis2 中使用WS-Security 的必需要求— Rampart 可以独立于代码使用的数据绑定技术实现WS-Security,因此它可以处理Axis2 支持的所有形式的数据绑定。
示例代码的根目录为jws04code。
在该目录内部,将找到Ant build.xml 和build.properties 文件,以及为示例应用程序提供服务定义的library.wsdl 文件,用于配置客户端登录的log4j.properties 文件,以及一些属性定义XML 文件(全部命名为XXX-policy-client.xml 或XXX-policy-server.xml)。
build.properties 文件配置示例应用程序的操作。
清单2 展示了这个属性文件的附带版本:
在尝试使用示例应用程序前,需要编辑build.properties 文件并将实际路径设置为Axis2 安装(添加了Rampart,如前一小节所述)。
如果对服务器使用了不同的主机或端口号,还需要修改host-name 和host-port 值。
我将在本文后面讨论其余的值。
尝试使用WS-Security
WS-Security 定义了一些不同的安全令牌类型(包括构成核心规范的令牌以及在配置文件中定义为规范的插件扩展的令牌),并定义了多种方法来构建和使用令牌。
本文的目的就是使用Axis2 配置和Rampart,因此我将使用最简单的令牌作为示例:由UsernameToken 配置文件定义的UsernameToken。
UsernameToken WS-SecurityPolicy
UsernameToken 的功能仅仅是将用户名和密码信息作为WS-Security 头部的一部分进行传递。
UsernameToken 的最基本形式就是以明文的方式发送用户名和密码。
从安全角度来看这并不合适(但是在安全连接之上使用这种方法并不会出问题),但是很容易看到发送的内容,因此是一个非常好的起点。
将UsernameToken 以文本形式发送的WS-SecurityPolicy 配置非常简单,如清单3 所示。
该策略(在这里将一行代码显示为两行以匹配页面宽度—实际使用时这样做是无效的)包含了一个标准WS- Policy 包装器(使用wsp 前缀的元素),用来封装一个WS-SecurityPolicy UsernameToken 断言。
清单3. 用于明文形式的UsernameToken 的WS-SecurityPolicy
清单3 中的UsernameToken 使用一个IncludeToken 属性指定将包含到令牌中的消息流的类型—在本例中,所有消息流从请求发起者(即客户机)流向请求接收者(即服务器)。
还可以为IncludeToken 属性定义其他值来指定不同的令牌用途,但是对于UsernameToken,这通常是惟一有效的值。
应用策略
WS-Policy 和WS-SecurityPolicy 旨在支持WSDL 服务定义中的内嵌功能。
使用引用将一个策略关联到一个或多个<wsdl:binding>、<wsdl:binding>/<wsdl:operation> 或
<wsdl:message> 定义。
Axis2 1.4.X 为WSDL 中内嵌的策略实现了初步处理,但是直到Axis2 1.4.1,实现仍然不够健壮。
本文将把策略直接连接到客户机和服务器,从而实现与1.4.1 代码的兼容性。
服务器端策略处理
在服务器端,应用策略的方式是将其添加到每个Axis2 .aar 服务归档中的services.xml 配置文件。
策略可以作为<service> 元素的子元素直接添加,以应用于服务定义的所有操作。
还需要向services.xml 添加一个<module> 元素,这是为了告诉Axis2 Rampart 模块必须包含在服务的配置中。
清单4 是示例应用程序使用的经过编辑的services.xml,其中粗体显示的是添加的模块引用和策略信息:
一个<ramp:RampartConfig> 元素。
该元素为策略信息提供了特定于Rampart 的扩展,在本例中,给出了将用于处理密码回调的类的名称。
服务器代码使用回调检验客户机在请求中提供的用户名和密码组合。
清单5 展示了回调类的实际实现,用于明文形式的密码。
在本例中,用户名和密码都被提供给回调,并且所有回调只需要检验用户名和密码组合。
如果用户名和密码匹配预期值,那么返回即可;否则,将抛出一个异常表示出错。
对于一个真正的应用程序,您肯定希望使用其他一些机制(比如数据库或外部安全机制)来检验用户名和密码组合。
回调技术可以让您使用任何检查技巧来扩展Rampart 安全处理。
客户端配置
要对客户机代码使用Rampart,首先需要对Axis2 使用模块。
方法就是针对客户机配置一个Axis2 库结构,但是更简单的方法是在您的类路径中包含rampart.mar 模块文件(以及需要使用的其他模块)。
提供的示例使用了类路径方法。
然后需要为客户机配置安全模块和其他相关参数。
处理此配置的最简单方法就是直接在服务stub 上设置值。
清单6 展示了示例代码中的配置过程:
配置内容包含在清单 6 中的最后一个代码块。
包括从创建的stub 中获得org.apache.axis2.client.ServiceClient 实例并在客户机选项中设置策略信息(从类路径加载)和用户名/密码。
随后在客户机使用的Axis2 配置中加入Rampart 模块。
完成这些操作后,可以使用stub 访问服务,就像不存在WS-Security 一样,而Rampart 将UsernameToken 自动添加到每个请求。
当然,仅仅用服务器运行客户机并不能向您表明发生的操作。
可以使用TCPMon 等工具充当客户机和服务器之间的中间层,从而捕获消息交换以查看WS-Security UsernameToken 的行为(见参考资料)。
为此,首先需要设置TCPMon 并在一个端口上接受来自客户机的连接,这个端口随后将连接转发给运行在不同端口(或不同主机)上的服务器。
然后可以编辑build.properties 文件并将host-port 的值修改为侦听TCPMon 的端口。
如果再一次在控制台中输入ant run,应当会看到消息发生了交换。
清单7 展示了一个样例客户机消息捕捉:
清单7. 使用UsernameToken 的客户机消息
保护UsernameToken
一个基本的明文形式的UsernameToken 并不能直接提供很强的安全性,因为用户名和相应的密码对于任何能够监视消息的人来说都是可见的。
如果使用加密的通信通道,那么就可以解决这个问题—只要通道加密非常可靠,外部无法监视消息。
WS-SecurityPolicy 方便地定义了一种方法来使用加密过的通道,如清单8 所示(同样,将一行代码分解为两行以匹配页面宽度—查看示例代码包的secure-policy- server.xml 文件获得真实的策略):
清单8. 要求HTTPS 连接的策略
清单8 中使用粗体显示的代码是新增的部分,由<sp:TransportBinding> 元素和嵌套的<sp:HttpsToken> 元素组成。
<sp:HttpsToken> 元素表示一个安全的HTTPS 连接必须用于与服务的通信。
如果尝试使用此策略构建service .aar(通过将build.properties 中的server- policy 值修改为secure-policy-server.xml,然后运行ant build-server)并部署它,将看到Rampart 实施这项策略需求,拒绝任何普通的HTTP 连接。
如果希望对服务使用一个HTTPS 连接,这样做是可行的,但是首先需要配置您的Web 服务器以支持HTTPS。
(Tomcat 提供了非常好的说明,可以从/tomcat-docs/ssl-howto.html 访问)。
还需要在build.properties 中将protocol 值修改为https,并且如果对Web 服务器使用的是自签名的证书,在运行Ant test 目标时需要向客户机发送一个证书存储库(trust store)。
提供的build.xml 有一个注释掉的行可以实现这点,因此只需去掉此行的注释符号,并设置相应的证书存储库文件在系统中的位置。
另一种增强UsernameToken 安全性的方法甚至可以处理未加密的链接。
这种方法使用对一个字符串计算得到的摘要(digest)值,该字符串由两个文本值和密码组成。
其中一个文本值为nonce,是由发送者对每个请求生成的随机值。
另一个文本值是一个生成的时间戳,表示发送者创建UsernameToken 的时间。
这两个值都以明文形式包含在UsernameToken 中。
如果恰当地应用于客户机和服务器,组合这些值和摘要中的密码使服务器能够验证在生成摘要时使用的是正确的密码,同时使得外部很难伪造有效的密码。
清单9 给出了一个
使用摘要密码的策略示例,其后是实际捕获的使用摘要密码的消息(全部重新格式化以适合页面宽度—查找hash-policy-client.xml 文件获得真实的策略),粗体显示的是与初始策略不同的地方。
结束语
在本文中,您了解了如何使用Axis2 和Rampart 实现基本的基于策略的WS-Security 处理。
在下一期Java Web 服务中,将了解WS-Security 的两个强大特性:XML 加密和签名。
使用XML 加密可以使您在操作任何类型的连接时保持消息内容的私密性,即使在处理过程中涉及到不可信的代理。
使用XML 签名可以确保消息确实来自声称的发起者,并且消息内容在传输过程中没有被篡改。
加密和签名是大多数企业安全实现的基础,回顾一下这些特性,看看如何在您自己的Web 服务中应用它们。
代码:
本文来自编程入门网:/Programming/Java/201110/30204_8.htm。