安全是许多类型的企业服务的主要要求。 尝试自己实施也是一个冒险的领域,因为即使是轻微而模糊的监督也可能导致严重的漏洞。 这些特性使安全处理的标准化具有吸引力,使许多专家可以为标准做出贡献,并避免任何个人的疏忽。 基于SOAP的Web服务可以将广泛支持的WS-Security和相关标准用于其安全需求,从而可以为每个服务配置适当的安全性。
Apache Axis2通过Rampart模块支持这些安全性标准(请参阅参考资料 )。 在本文中,您将看到如何在Axis2上安装,配置和使用Rampart,以实现在服务请求中发送用户名和密码的基本安全功能。 在本系列的后续专栏中,您将学习如何将Rampart用于更复杂的安全性形式。
WS-安全性
WS-Security是为SOAP Web服务消息交换添加安全性的标准(请参阅参考资料 )。 它使用SOAP消息头元素将安全信息附加到消息上,形式为令牌 , 令牌传达不同类型的声明(可以包括名称,身份,密钥,组,特权,功能等)以及加密和加密。数字签名信息。 WS-Security支持令牌的多种格式,多种信任域,多种签名格式和多种加密技术,因此在大多数情况下,标头信息需要包括每个组件的特定格式和算法标识。 添加的信息可能导致标头信息的结构复杂,如清单1所示(经过大量编辑)—带有签名和加密的示例消息:
清单1.带有签名和加密的示例消息
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ...>
<soap:Header>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-d2e3c4aa-da82-4138-973d-66b596d66b2f">
<wsu:Created>2006-07-11T21:59:32Z</wsu:Created>
<wsu:Expires>2006-07-12T06:19:32Z</wsu:Expires>
</wsu:Timestamp>
<wsse:BinarySecurityToken ValueType="...-x509-token-profile-1.0#X509v3"
EncodingType="...-wss-soap-message-security-1.0#Base64Binary"
xmlns:wsu="...oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="SecurityToken-faa295...">MIIEC56MQswCQY...</wsse:BinarySecurityToken>
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier ValueType=
"...#X509SubjectKeyIdentifier">LlYsHyhNnOVA9Aj7...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>g+A2WJhsoGBKUydZ9Za...</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncryptedContent-ba0556c3-d443-4f34-bcd1-14cbc32cd689" />
</xenc:ReferenceList>
</xenc:EncryptedKey>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#Id-c80f735c-62e9-4001-8094-702a4605e429">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>lKjc5nyLQDZAIu/hZb4B6mLquow=</DigestValue>
</Reference>
...
</SignedInfo>
<SignatureValue>TiLmWvlz3mswinLVQn58BgYS0368...</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-faa295..."
ValueType="...-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soap:Header>
<soap:Body wsu:Id="Id-8db9ff44-7bef-4737-8091-cdac51a34db8">
<xenc:EncryptedData Id="EncryptedContent-ba05..."
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>mirmi0KuFEEI56eu2U3cICz...</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>
在本文中,您将看到仅带有单个令牌的WS-Security标头的一些简单示例。 该系列的下一篇文章将进一步讨论清单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服务描述语言(WSDL)文档中,以便Web服务框架可以根据服务需求自动进行配置。
城墙介绍
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目录中)。 为了将Rampart与Axis2一起使用,必须将.jar文件添加到类路径中,并且必须将.mar文件添加到类路径或Axis2存储库结构中。
处理Rampart .jar和.mar文件的最简单方法是将它们添加到Axis2安装中。 您可以直接将Rampart lib目录中的.jar文件复制到Axis2 lib目录中,而将Rampart dist目录中的.mar文件直接复制到Axis2存储库/模块目录中。 (您还可以使用Rampart样本目录中的Ant build.xml将文件复制到Axis2安装中。只需将AXIS2_HOME
环境变量设置到Axis2安装目录中,然后从打开到Rampart样本目录的控制台中运行ant
。)
对于许多WS-Security功能,您还需要将Bouncy Castle安全提供程序添加到JVM安全配置中,并将Bouncy Castle .jar添加到Axis2安装中。 此步骤(本文将要学习的UsernameToken
不需要此步骤)是该系列后面的其他安全功能所必需的。 由于与一些安全算法的专利问题,在充气城堡的.jar是从兰帕特单独下载(参见相关主题 )。 下载适合您的Java运行时的.jar版本,并将.jar添加到Axis2 lib目录中。 然后,您需要通过在Java运行时的lib / security目录中的java.security文件中添加一行来修改Java安装的安全策略,以使用Bouncy Castle代码。 使用几行不同的security.provider
行查找文件部分,然后添加以下行:
security.provider.99=org.bouncycastle.jce.provider.BouncyCastleProvider
该文件中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安装dist目录中找到创建的axis2.war Web应用程序。
样例应用程序
示例代码中提供的应用程序(请参阅可下载的资源 )基于我之前用来演示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显示了此属性文件的提供的版本:
清单2.提供的build.properties文件
# set axis-home to your Axis2 installation directory
axis-home=PATH_TO_AXIS2_INSTALLATION
# set the connection protocol to be used to access services (http or https)
protocol=http
# set the name of the service host
host-name=localhost
# set the port for accessing the services (change this for monitoring)
host-port=8080
# set the base path for accessing all services on the host
base-path=/axis2/services/
# set the name of the policy file to be used by the client
client-policy=plain-policy-client.xml
# set the name of the policy file to be used by the server
server-policy=plain-policy-server.xml
在尝试示例之前,您需要编辑build.properties文件并设置Axis2安装的实际路径(如上一节所述,添加了Rampart)。 如果为服务器使用其他主机或端口号,则还需要修改host-name
和host-port
值。 我将在本文后面讨论剩余的值。
尝试WS-Security
WS-Security定义了几种类型的安全性令牌(包括作为核心规范一部分的令牌,以及由概要文件定义为该规范的插件扩展的那些令牌),以及有关如何构造和使用令牌的许多选项。 本文的重点是Rampart与Axis2的配置和使用,因此我将仅以最简单有用的令牌为例: UsernameToken
,由UsernameToken
配置文件定义。
UsernameToken
WS-SecurityPolicy
UsernameToken
的目的只是将用户名和密码信息作为WS-Security标头的一部分进行传达。 UsernameToken
最基本形式以纯文本形式发送用户名和密码。 从安全角度来看,这并不是最佳选择(尽管在安全连接上使用此方法没有任何问题),但是很容易看到正在发送的内容,这使其成为有用的起点。
以文本形式发送的UsernameToken
的WS-SecurityPolicy配置可以像清单3所示那样简单。 此策略(此处显示为一行,一分为二以适合页面宽度-不适用于实际使用)由围绕WS-SecurityPolicy UsernameToken
断言的标准WS-Policy包装器(使用wsp
前缀的元素)组成。
清单3.用于纯文本UsernameToken
WS-SecurityPolicy
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/
ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
清单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的编辑版本,添加的模块参考和策略信息以粗体显示:
清单4.具有嵌入式策略的services.xml
<serviceGroup>
<service name="library-username">
<messageReceivers>
<messageReceiver
class="com.sosnoski.ws.library.adb.LibraryUsernameMessageReceiverInOut"
mep="http://www.w3.org/ns/wsdl/in-out"/>
</messageReceivers>
<parameter
name="ServiceClass">com.sosnoski.ws.library.adb.LibraryUsernameImpl</parameter>
<parameter name="useOriginalwsdl">true</parameter>
<parameter name="modifyUserWSDLPortAddress">true</parameter>
<operation mep="http://www.w3.org/ns/wsdl/in-out" name="getBook"
namespace="http://ws.sosnoski.com/library/wsdl">
<actionMapping>urn:getBook</actionMapping>
<outputActionMapping>http://.../getBookResponse</outputActionMapping>
</operation>
...
<module ref="rampart"/>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://.../oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="UsernameToken">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://.../IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:HashPassword/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClass>...PWCBHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</service>
</serviceGroup>
如果你比较在嵌入式政策清单4与基本政策清单3 ,你会看到一个加法-一个<ramp:RampartConfig>
元素。 该元素为策略信息提供特定于Rampart的扩展,在这种情况下,提供了用于处理密码回调的类的名称。 回调是服务器代码如何验证客户端根据请求提供的用户名和密码组合的方式。
清单5显示了用于纯文本密码的回调类的实际实现。 在这种情况下,用户名和密码都将提供给回调,并且所有回调需要做的就是验证组合。 如果用户名和密码与期望值匹配,则仅返回; 否则,它将引发异常以指示错误。
清单5.密码回调代码
import org.apache.ws.security.WSPasswordCallback;
public class PWCBHandler implements CallbackHandler
{
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
String id = pwcb.getIdentifer();
if (pwcb.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
// used when plain-text password in message
if (!"libuser".equals(id) || !"books".equals(pwcb.getPassword())) {
throw new UnsupportedCallbackException(callbacks[i], "check failed");
}
}
}
}
}
对于真实的应用程序,您自然会希望使用其他某种机制(例如数据库或外部安全机制)来验证用户名和密码的组合。 回调技术使您可以将所需的任何验证技术用作Rampart安全处理的扩展。
客户端配置
要将Rampart用于客户端代码,首先需要使该模块可用于Axis2。 您可以通过为客户端配置Axis2存储库结构来完成此操作,但是通常仅在类路径中包含rampart.mar模块文件(以及需要使用的任何其他模块)会更容易。 提供的示例使用类路径方法。
然后,您需要为客户端配置安全策略和任何相关参数。 处理此配置的最简单方法是直接在服务存根上设置值。 清单6显示了如何在示例代码中完成配置:
清单6.客户端配置
/**
* Load policy file from classpath.
*/
private static Policy loadPolicy(String name) throws XMLStreamException {
ClassLoader loader = WebServiceClient.class.getClassLoader();
InputStream resource = loader.getResourceAsStream(name);
StAXOMBuilder builder = new StAXOMBuilder(resource);
return PolicyEngine.getPolicy(builder.getDocumentElement());
}
public static void main(String[] args) throws IOException, XMLStreamException {
// check for required command line parameters
if (args.length < 4) {
System.out.println("Usage:\n java " +
"com.sosnoski.ws.library.adb.WebServiceClient protocol host port path");
System.exit(1);
}
// create the client stub
String target = args[0] + "://" + args[1] + ":" + args[2] + args[3];
System.out.println("Connecting to " + target);
LibraryUsernameStub stub = new LibraryUsernameStub(target);
// configure and engage Rampart
ServiceClient client = stub._getServiceClient();
Options options = client.getOptions();
options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,
loadPolicy("policy.xml"));
options.setUserName("libuser");
options.setPassword("books");
client.engageModule("rampart");
配置部分是清单6中的最后一个代码块。这将从创建的存根中获取org.apache.axis2.client.ServiceClient
实例,并在客户端选项中设置策略信息(从类路径加载)和用户名/密码。 然后,它将Rampart模块接合到客户端使用的Axis2配置中。 完成此操作后,您可以像没有WS-Security一样使用存根访问服务,并且Rampart会自动将UsernameToken
添加到每个请求。
确认结果
安装Ant后,您可以从打开示例控制台的控制台中运行ant
来构建客户端和服务器代码。 然后,您可以将创建的library-username.aar文件部署到Axis2服务器安装中(当然,其中包括Rampart .jars和.mars),并通过在控制台输入ant run
尝试客户端。 如果一切设置正确,您应该看到如图1所示的输出:
图1.运行应用程序时的控制台输出
当然,仅在服务器上运行客户端不会显示正在发生的事情。 您可以使用诸如TCPMon之类的工具充当客户端和服务器之间的中介,并捕获消息交换以查看WS-Security UsernameToken
的实际作用(请参阅参考资料 )。 为此,您首先需要设置TCPMon并从一个端口上接受客户端的连接,然后将其转发到在其他端口(或其他主机)上运行的服务器。 然后,您可以编辑build.properties文件,并将host-port
值更改为TCPMon的侦听端口。 如果再次在控制台上输入ant run
,则应该看到正在交换的消息。 清单7显示了一个示例客户端消息捕获:
清单7.带有UsernameToken
客户端消息
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="...wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="...wss-wssecurity-utility-1.0.xsd"
wsu:Id="UsernameToken-1815911473">
<wsse:Username>libuser</wsse:Username>
<wsse:Password Type="...wss-username-token-profile-1.0#PasswordText"
>books</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns2:getBooksByType xmlns:ns2="http://ws.sosnoski.com/library/wsdl">
<ns2:type>scifi</ns2:type>
</ns2:getBooksByType>
</soapenv:Body>
</soapenv:Envelope>
保护UsernameToken
基本的纯文本UsernameToken
不能直接提供很多安全性,因为能够监视消息的任何人都可以看到用户名和相应的密码。 如果您使用加密的通信通道,这不是真正的问题-只要通道加密可靠,任何外部方都无法监视消息。 WS-SecurityPolicy方便地定义了一种要求使用加密通道的方法,如清单8所示(再次将行拆分为适合页面宽度—有关实际策略,请参见示例代码包的secure-policy-server.xml文件) :
清单8.需要HTTPS连接的策略
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/
ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
清单8中以粗体显示的部分是添加的部分,由<sp:TransportBinding>
元素和嵌套的<sp:HttpsToken>
元素组成。 <sp:HttpsToken>
元素表示,在与服务进行通信时必须使用安全的HTTPS连接。 如果尝试使用此策略构建服务.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
目标时需要将信任存储传递给客户端。 提供的build.xml具有注释行来执行此操作,因此您只需取消注释该行并设置系统上适当的信任库文件的位置即可。
使UsernameToken
更安全的另一种方法甚至可以在未加密的链接上使用。 此方法使用摘要值,该摘要值是根据由其他两个文本值与密码组成的字符串计算得出的。 文本值之一, nonce是发件人为每个请求生成的随机值。 另一个就是创建的时间戳,它只是发送者创建UsernameToken
。 这两个值都以纯文本形式包含在UsernameToken
中。 当客户端和服务器都正确使用这些值时,这些值与摘要中的密码结合使用可使服务器验证生成摘要时是否使用了正确的密码,同时使任何外部方都难以伪造密码。有效的密码。 清单9给出了一个使用摘要密码的策略示例,然后使用摘要密码对消息进行了实际捕获(二者均重新格式化为适合页面宽度—有关实际策略,请参见hash-policy-client.xml文件)。 与原始政策的差异再次以粗体显示。
清单9.使用密码摘要的策略和示例消息
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/
ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:HashPassword/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse=".../oasis-200401-wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="...wss-wssecurity-utility-1.0.xsd"
wsu:Id="UsernameToken-1421876889">
<wsse:Username>libuser</wsse:Username>
<wsse:Password Type="...wss-username-token-profile-1.0#PasswordDigest"
>/Wt/2yDdZwa8a5qd7U70hrp29/w=</wsse:Password>
<wsse:Nonce>4ZQz5ytME/RXfChuKJ03iA==</wsse:Nonce>
<wsu:Created>2009-03-17T11:20:57.467Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns2:getBooksByType xmlns:ns2="http://ws.sosnoski.com/library/wsdl">
<ns2:type>scifi</ns2:type>
</ns2:getBooksByType>
</soapenv:Body>
</soapenv:Envelope>
Wrapping up
在本文中,您已经了解了如何将Axis2和Rampart用于基于策略的WS-Security处理的基本形式。 在下一个Java Web服务系列中,您将了解WS-Security的两个强大功能:XML加密和签名。 使用XML加密可以使您在通过任何类型的连接进行操作时都将消息内容保密,即使处理过程中涉及了不受信任的中介也是如此。 使用XML签名可以保证消息确实来自声明的原始发件人,并且消息内容在传输过程中没有被篡改。 加密和签名是大多数企业安全性实现的基础,因此请回来查看如何在自己的Web服务中应用这些功能。
翻译自: https://www.ibm.com/developerworks/java/library/j-jws4/index.html