`

Metro 服务下的 WS-Security

    博客分类:
  • SOA
阅读更多

本文展示如何通过 Metro 来使用和配置 WS-Security,将其作为一个独立的 Web 应用程序在 Glassfish 服务器外部使用。参见 下载 部分获取本文中的全部示例的完整源代码,该代码实现了此前在本系列中使用的简单图书馆管理服务。

WSIT 基础

WSIT 负责配置 Metro 运行时以匹配一个服务的 WS-Policy 规范,包括诸如 WS-SecurityPolicy 之类的 WS-Policy 扩展。除标准的 WS-Policy 扩展外,Metro 还使用策略文档中的自定义扩展来配置实现安全处理所需的用户信息(如密匙存储位置和密码)。

WSIT 从 Web Services Description Language (WSDL) 服务描述中获取策略信息。在客户端,这可能难以理解一些,因为用于 WSIT 配置的 WSDL 与用于定义 JAX-WS 服务的 WSDL 是分开的。如 “Metro 简介 ” 所述,用于配置 JAX-WS 客户端的 WSDL 可以直接从服务获取,也可以从生成 JAX-WS 代码之时指定的位置获取。WSIT 使用的 WSDL 有一个固定的文件名(虽然这个文件能够使用一个 <wsdl:import> 标记来引用一个带有完整 WSDL 的独立文件),并且总是通过类路径访问。

在服务器端,WSIT 要求在 WEB-INF/sun-jaxws.xml 配置文件(在 “Metro 简介 ” 中介绍过)中指定的位置提供 WSDL。所提供的 WSDL 必须包含用于为 WSIT 配置用户信息的自定义扩展,但是这些自定义扩展在为响应对服务端点的 HTT PGET 请求而提供的 WSDL 版本中被删除掉了。

这些用于配置 WSIT 用户信息的自定义扩展在服务器端和客户端看起来一样,但是在用于扩展元素的 XML 名称空间中不同。在客户端,名称空间是 http://schemas.sun.com/2006/03/wss/client ;在服务器端,名称空间是 http://schemas.sun.com/2006/03/wss/server

Metro 中的 UsernameToken

Axis2 WS-Security 基础 ” 使用了一个简单的 UsernameToken 例子来介绍 Axis2/Rampart 环境下的 WS-Security。UsernameToken 提供了一种通过 WS-Security 来表示 “用户名/密码” 对的标准方法。密码信息可以以纯文本方式(通常,这种方式只有在同时配置了传输层安全协议(Transport Layer Security,TLS)或者使用 WS-Security 加密时才会在生产中使用 — 但是这种方式确实便于测试)或者以散列值方式发送。

要在 Metro 上实现一个简单的纯文本格式的 UsernameToken 示例,您需要在 WSDL 服务定义中恰当定义 WS-Policy/WS-SecurityPolicy。清单 1 展示了 “Metro 简介 ” 中使用过的一个基础 WSDL 服务定义的修订版,包含了在从客户端到服务器的请求上要求 UsernameToken 的策略信息。与策略本身一样,<wsdl:binding> 中的策略引用以粗体显示。


清单 1. 纯文本 UsernameToken WSDL

				
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"
    xmlns:wns="http://ws.sosnoski.com/library/wsdl"
    xmlns:tns="http://ws.sosnoski.com/library/types"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">
  <wsdl:types>
    ...
  </wsdl:types>

  <wsdl:message name="getBookRequest">
    <wsdl:part element="wns:getBook" name="parameters"/>
  </wsdl:message>
  ...

  <wsdl:portType name="Library">
    <wsdl:operation name="getBook">
      <wsdl:input message="wns:getBookRequest" name="getBookRequest"/>
      <wsdl:output message="wns:getBookResponse" name="getBookResponse"/>
    </wsdl:operation>
    ...
  </wsdl:portType>

  <wsdl:binding name="LibrarySoapBinding" type="wns:Library">
  
    <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
        URI="#UsernameToken"/>


    <wsdlsoap:binding style="document"
        transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getBook">
      <wsdlsoap:operation soapAction="urn:getBook"/>
      <wsdl:input name="getBookRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getBookResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    ...
  </wsdl:binding>

  <wsdl:service name="MetroLibrary">
    <wsdl:port binding="wns:LibrarySoapBinding" name="library">
      <wsdlsoap:address location="http://localhost:8080/metro-library-username"/>
    </wsdl:port>
  </wsdl:service>
  
  <!-- Policy for Username Token with plaintext password, sent from client to
    server only -->
  <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=".../IncludeToken/AlwaysToRecipient"/>
          </wsp:Policy>
        </sp:SupportingTokens>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>


</wsdl:definitions>

 

清单 1 WSDL 告诉我们,要访问服务需要进行哪些安全处理。您需要同时在服务器端和客户端向策略信息中添加 WSDL 自定义扩展,通过用户配置细节表明如何实现安全处理。这些自定义扩展被加入到了 WSDL 中的 <wsp:Policy> 组件。下一步,我将向您展示每一端的扩展示例。

客户端应用

在客户端,使用一个名为 wsit-client.xml (这个文件名是固定的)的文件来进行 WSIT 配置。这个文件必须位于根目录的路径下(不在任何包中),或者在类路径的一个目录的 META-INF 子目录中。而 wsit-client.xml 必须是能直接提供全部 WSDL 服务或通过 <wsdl:import> 引用某个独立的 WSDL 服务定义的 WSDL 文档。无论哪一种方式,WSDL 都必须包含 WS-Policy/WS-SecurityPolicy 的全部要求和 WSIT 配置扩展。

清单 2 展示了 清单 1 WSDL 中的策略部分,通过添加一个 WSIT 自定义扩展来配置客户端 UsernameToken 支持。在这里,那个自定义扩展是 <wssc:CallbackHandlerConfiguration> 元素及其子元素,以粗体显示。两个 <wssc:CallbackHandler> 子元素定义回调类,第一个定义用户名(name="usernameHandler" ),第二个定义密码(name="passwordHandler" )。指定的类必须实现 javax.security.auth.callback.CallbackHandler 接口。


清单 2. 带有 WSIT 客户端扩展的 UsernameToken 策略

				
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu=
    "http://docs.oasis-open.org/wss/2004/01/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=".../IncludeToken/AlwaysToRecipient"/>
        </wsp:Policy>
      </sp:SupportingTokens>
      <wssc:CallbackHandlerConfiguration wspp:visibility="private"
          xmlns:wssc="http://schemas.sun.com/2006/03/wss/client"
          xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
        <wssc:CallbackHandler name="usernameHandler"
            classname="com.sosnoski.ws.library.metro.UserPassCallbackHandler"/>
        <wssc:CallbackHandler name="passwordHandler"
            classname="com.sosnoski.ws.library.metro.UserPassCallbackHandler"/>
      </wssc:CallbackHandlerConfiguration>

    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

 

清单 2 中,所有的回调必须使用相同的类。清单 3 是回调类的代码,作用是检查每个回调请求的类型并恰当地为其赋值:


清单3. 客户端回调代码

				
public class UserPassCallbackHandler implements CallbackHandler
{
    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof NameCallback) {
                ((NameCallback)callbacks[i]).setName("libuser");
            } else if (callbacks[i] instanceof PasswordCallback) {
                ((PasswordCallback)callbacks[i]).setPassword("books".toCharArray());
            } else {
                throw new UnsupportedCallbackException(callbacks[i],
                    "Unsupported callback type");
            }
        }
    }
}

 

您并不是必须 使用回调来设置用户名或密码。如果用户名和密码被赋予的是固定值,您可以直接在 <wssc:CallbackHandler> 元素中设置它们,方法是使用 default="yyy " (在这里,属性值即实际的用户名和密码)来替换 classname="xxx " 属性。

服务器端应用

在服务器端,WSIT 配置信息需要包含在 WSDL 服务定义中。如 “Metro 简介 ” 所述,服务 WSDL 的位置可以在服务 WAR 文件中的 WEB-INF/sun-jaxws.xml 里指定为一个参数。如果不使用 WSIT 特性,则 WSDL 是可选的;在这种情况下,WSDL 将在运行时自动生成。如果使用 WSIT 功能,则 WSDL 是必须的,并且必须包含为服务所用的特性配置 WSIT 所需的任意自定义扩展元素。清单 4 展示了 清单 1 WSDL 服务的策略部分,这次添加了一个 WSIT 自定义扩展元素来配置 UsernameToken 支持(以粗体显示):


清单 4. 带有 WSIT 服务器端扩展的 UsernameToken 策略

				
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu=
    "http://docs.oasis-open.org/wss/2004/01/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=".../IncludeToken/AlwaysToRecipient"/>
        </wsp:Policy>
      </sp:SupportingTokens>
      <wsss:ValidatorConfiguration wspp:visibility="private"
          xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"
          xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
        <wsss:Validator name="usernameValidator"
            classname="com.sosnoski.ws.library.metro.PasswordValidator"/>
      </wsss:ValidatorConfiguration>

    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

 

清单 4 中的服务器端 WSIT 扩展以 <wsss:ValidatorConfiguration> 元素和 <wsss:Validator> 子元素形式表示,指定将作为验证器回调使用的类。清单 5 给出了这个类的代码,这个类必须实现 com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidator 接口。在这里,它只是针对固定值检查提供的用户名和密码,但它可以轻松使用一个数据库查询或其他机制替代。


清单5. 服务器回调代码

				
public class PasswordValidator implements PasswordValidationCallback.PasswordValidator
{
    public boolean validate(Request request) throws PasswordValidationException {
        PasswordValidationCallback.PlainTextPasswordRequest ptreq 
            = (PasswordValidationCallback.PlainTextPasswordRequest)request;
        return "libuser".equals(ptreq.getUsername()) &&
            "books".equals(ptreq.getPassword());
    }
}

 

Metro 策略工具

Metro/WSIT 要求您向 WSDL 文件添加配置信息,就像使用 Axis2/Rampart 一样。这个系列中此前介绍 Axis2/Rampart 的文章在构建过程中使用了一种特殊的策略工具来根据需要生成经过修改的 WSDL 文件。本文的示例代码 下载 部分包含一种相似的工具,它根据 Metro/WSIT 的需要而设计。

这个工具就是 com.sosnoski.ws.MergeTool 应用程序,在示例代码的 mergetool 目录中。MergeTool 用于将数据合并到目标 XML 文件中,匹配嵌套的 XML 元素,找到需要合并的数据并在目标文档中确定数据的合并点。示例程序的 build.xml 使用 MergeTool 将客户端或服务器的 WSIT 配置信息添加到服务的 WSDL 中。如果愿意,您也可以在自己的应用程序中使用 MergeTool — mergetool/readme.txt 文件包含一些基础的使用说明,您也可以在提供的构建中看到 MergeTool 的使用方法。

如果没有 <wsss:ValidatorConfiguration> ,Metro 将使用您的 Web 应用程序容器(提供 servlet 的 Web 服务器)所提供的授权机制。

构建并运行示例代码

在调试示例代码之前,您需要在您的操作系统中下载并且安装一个最新版本的 Metro(本代码是在 1.5 发布版中测试的,参见 参考资料 )。您还需要对解压后的示例代码 下载 根目录下的 build.properties 文件进行一些编辑,把 metro-home 属性值改成您的 Metro 安装路径。如果您还打算测试一个不同操作系统或端口上的服务器,那么您需要修改 host-namehost-port

要使用已提供的 Ant build.xml 构建示例应用程序,需要对下载代码的根目录和 ant 类型打开控制台。这将首先调用 JAX-WS wsimport 工具(包含在 Metro 发行版中),然后构建客户端和服务器,最后把服务器端代码打包为一个 WAR(这个过程将生成包含客户端与服务器 WSIT 配置信息的服务 WSDL 的独立版本)。注意,包含在 Metro 1.5 中的 wsimport 版本会弹出一条警告信息(因为该工具在处理 WSDL 中嵌套的模式时有一个怪癖):src-resolve: Cannot resolve the name 'tns:BookInformation' to a(n) 'type definition' component

这时您可以将 metro-library.war 文件部署到您的测试服务器中,然后在控制台上输入 ant run 来运行示例客户端。示例客户端将向服务器发送一系列请求,并输出每个请求的简单结果。

在 Metro 中签名与加密

UsernameToken 的简洁性使其成为一个不错的起点, 但这并不是 WS-Security 的典型应用。在大多数情况下,您可能会使用签名,或者加密,或者两者都使用。清单 6 展示了一个修改过的、同时使用签名与加密的 WSDL 示例(基于 “Axis2 WS-Security 签名和加密 ” 中的示例 — 请参考那篇文章了解关于 WS-Security 签名与加密技术的详细信息)。WSDL 的策略部分以粗体显示。


清单 6. 签名/加密 WSDL

				
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"
    xmlns:wns="http://ws.sosnoski.com/library/wsdl"
    xmlns:tns="http://ws.sosnoski.com/library/types"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">
  <wsdl:types>
    ...
  </wsdl:types>

  <wsdl:message name="getBookRequest">
    <wsdl:part element="wns:getBook" name="parameters"/>
  </wsdl:message>
  ...

  <wsdl:portType name="Library">
    <wsdl:operation name="getBook">
      <wsdl:input message="wns:getBookRequest" name="getBookRequest"/>
      <wsdl:output message="wns:getBookResponse" name="getBookResponse"/>
    </wsdl:operation>
    ...
  </wsdl:portType>

  <wsdl:binding name="LibrarySoapBinding" type="wns:Library">
  
    <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
        URI="#SignEncr"/>


    <wsdlsoap:binding style="document"
        transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getBook">
      <wsdlsoap:operation soapAction="urn:getBook"/>
      <wsdl:input name="getBookRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getBookResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    ...
  </wsdl:binding>

  <wsdl:service name="MetroLibrary">
    <wsdl:port binding="wns:LibrarySoapBinding" name="library">
      <wsdlsoap:address location="http://localhost:8080/metro-library-username"/>
    </wsdl:port>
  </wsdl:service>
  
  <!-- Policy for first signing and then encrypting all messages, with the certificate
   included in the message from client to server but only a thumbprint on messages from
   the server to the client. -->
  <wsp:Policy wsu:Id="SignEncr" 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:AsymmetricBinding
            xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:InitiatorToken>
              <wsp:Policy>
                <sp:X509Token sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
                  <!-- Added this policy component so Metro would work with the same
                   certificates (and key stores) used in the Axis2/Rampart example. -->
                  <wsp:Policy>
                    <sp:RequireThumbprintReference/>
                  </wsp:Policy>
                </sp:X509Token>
              </wsp:Policy>
            </sp:InitiatorToken>
            <sp:RecipientToken>
              <wsp:Policy>
                <sp:X509Token sp:IncludeToken=".../IncludeToken/Never">
                  <wsp:Policy>
                    <sp:RequireThumbprintReference/>
                  </wsp:Policy>
                </sp:X509Token>
              </wsp:Policy>
            </sp:RecipientToken>
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:TripleDesRsa15/>
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <sp:Layout>
              <wsp:Policy>
                <sp:Strict/>
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp/>
            <sp:OnlySignEntireHeadersAndBody/>
          </wsp:Policy>
        </sp:AsymmetricBinding>
        <sp:SignedParts
            xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <sp:Body/>
        </sp:SignedParts>
        <sp:EncryptedParts
            xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <sp:Body/>
        </sp:EncryptedParts>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>


</wsdl:definitions>

 

清单 6 WSDL 与先前的 Axis2/Rampart 示例中使用过的 WSDL 的唯一重要区别是:当 X509 证书没有被包含到一条信息中时,需要向 <sp:InitiatorToken> 组件添加一个要求使用拇指指纹引用的策略,其原因是 Metro 和 Axis2 中引用的默认处理方式不同。

当客户端(在 WS-SecurityPolicy 术语中称为发起者 )发送一条信息时,客户端的 X.509 证书也作为信息的一部分发送(因为<sp:InitiatorToken/wsp:Policy/sp:X509Token> 元素上的 sp:IncludeToken=".../IncludeToken/AlwaysToRecipient" 属性),然后服务器使用该证书进行签名验证。当服务器对客户端进行应答时,进行加密处理时需要引用那个证书。如果没有指定其他方法,Axis2/Rampart 默认使用一个拇指指纹引用进行证书识别。Metro/WSIT 默认使用另一种方法,称为主体密匙标识符 (subject key identifier,SKI)。Axis2/Rampart 示例中使用的证书的形式并不支持 SKI,所以它们默认不能用于 Metro/WSIT。向策略中添加 <sp:RequireThumbprintReference/> 元素告知 Metro/WSIT 使用拇指指纹引用来代替证书。

这种策略改变使先前的 Axis2/Rampart 示例使用的证书和密匙存储可以在现在的示例中使用。这还使 Axis2/Rampart 客户端示例可以与 Metro/WSIT 服务器一起使用,反之也然,从而作为一种检查互操作性的便捷方式。如果您进行这种尝试(方法是修改每次传送到测试客户端的目标路径),就会发现大部分消息 可以毫不费力地交换 — 但是在实际操作中有一个问题,这将在下面的 互操作性问题 小节进行讨论。

UsernameToken 示例一样,WSIT 需要客户端与服务器上存在针对策略信息的自定义扩展,以便提供详细的附加配置信息。

客户端应用

清单 7 展示了向 WSDL 策略添加的自定义扩展,用于针对本示例配置客户端处理方式。这些自定义扩展(以粗体显示)配置密匙存储(包含客户端的私有密匙以及对应的证书)和签名与加密所需的可信存储(包含服务器证书)。


清单 7. 使用 WSIT 客户端扩展签署并加密策略

				
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
wsu:Id="SignEncr">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:AsymmetricBinding xmlns:sp=
      "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <wsp:Policy>
          ...
        </wsp:Policy>
      </sp:AsymmetricBinding>
      <sp:SignedParts
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <sp:Body/>
      </sp:SignedParts>
      <sp:EncryptedParts
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <sp:Body/>
      </sp:EncryptedParts>
    
      <wssc:KeyStore alias="clientkey" keypass="clientpass"
          location="client.keystore" storepass="nosecret"
          xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" wspp:visibility="private"
          xmlns:wssc="http://schemas.sun.com/2006/03/wss/client"/>
      <wssc:TrustStore location="client.keystore" peeralias="serverkey"
          storepass="nosecret" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
          wspp:visibility="private"
          xmlns:wssc="http://schemas.sun.com/2006/03/wss/client"/>

    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

 

清单 7 WSIT 自定义扩展提供了访问密匙存储和可信存储(在本例中是同一个文件)所需的全部参数,包括访问客户端的私有密匙所需的密码(<wssc:KeyStore> 元素上的 keypass="clientpass" 属性)。也可以使用回调获取密码信息,这将在下节介绍。

已命名的密匙存储和可信存储必须放在类路径目录下的 META-INF 子目录中。也可以对这些文件使用绝对路径 — 而不是仅仅使用文件名 — 这允许您在文件系统的任意固定地址定位它们。(回想一下,对于客户端,包含 WSIT 自定义扩展的 WSDL 必须使用固定名称 wsit-client.xml,而且必须在类路径的根目录下或者类路径根目录下的 META-INF子目录中)。

服务器端应用

添加到 WSDL 的服务器端 WSIT 自定义扩展在清单 8 中展示(同样以粗体显示)。在本例中,<wsss:KeyStore>keypass 属性给出的是一个类名而不是具体的密码值(像 清单 7 客户端示例一样)。如果您使用这种方法,被引用的类必须实现 javax.security.auth.callback.CallbackHandler 接口;当该类需要访问秘密密匙的密码时,它将被 WSIT 代码调用。对于 storepass 值,您也可以使用相同的技术来指定一个类而不是密码。


清单 8. 使用 WSIT 服务器端扩展签署并加密策略

				
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
wsu:Id="SignEncr">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:AsymmetricBinding xmlns:sp=
      "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <wsp:Policy>
          ...
        </wsp:Policy>
      </sp:AsymmetricBinding>
      <sp:SignedParts
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <sp:Body/>
      </sp:SignedParts>
      <sp:EncryptedParts
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <sp:Body/>
      </sp:EncryptedParts>
    
      <wsss:KeyStore alias="serverkey"
          keypass="com.sosnoski.ws.library.metro.KeystoreAccess"
          location="server.keystore" storepass="nosecret"
          xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" wspp:visibility="private"
          xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"/>
      <wsss:TrustStore location="server.keystore" storepass="nosecret"
          xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" wspp:visibility="private"
          xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"/>

    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

 

清单 9 展示了这个示例使用的 CallbackHandler 接口的实现:


清单 9. 服务器密匙存储密码回调代码

				
public class KeystoreAccess implements CallbackHandler
{
    public void handle(
       Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            Callback callback = callbacks[i];
            if (callback instanceof PasswordCallback) {
                ((PasswordCallback)callback).setPassword("serverpass".toCharArray());
            } else {
                throw new UnsupportedCallbackException(callback, "unknown callback");
            }
        }
    }
}

 

构建并运行示例代码

签名与加密示例使用的 构建步骤UsernameToken 示例相同,但是您必须修改 build.properties 文件以使用 variant-name=signencr (而不是 UsernameToken 示例使用的 username )。

互操作性问题

如果您使用 Axis2/Rampart 客户端与 Metro/WSIT 服务器(或者相反),当客户端尝试添加一本国际标准书籍编号(International Standard Book Number,ISBN)相同的书时,您可能会遇到问题。在这种情况下,服务器将返回一个 Fault,而不是通常的 SOAP 响应消息。Axis2/Rampart 1.5.x 发布版正确地执行了 WSDL 在这里要求的签名与加密处理,但是 Metro/WSIT 1.5 却没有,结果造成客户端出错。这是 WSIT 代码中的错误,在下一个版本的 Metro 中应该会得到更正。

如果您运行版本低一些的 Axis2/Rampart,您可能不会遇到任何问题 — 因为 Rampart 直到 1.5 版本才出现了这个 bug。

结束语

Metro 对 WS-SecurityPolicy 的 WSIT 支持既允许直接配置用户名和密码等参数(包括密钥存储和私有密钥密码),也可以根据需要通过回调来设置这些值。它还允许您选择使用 servlet 容器的授权处理机制或者您自己的回调来在服务器上验证用户名和密码组合。这种灵活性使得 Metro 能够轻松满足各种类型的应用程序的需要。Metro 通过多个集成组件提供 WSIT/XWSS WS-Security 支持,而不是像 Axis2 和 Rampart 那样使用一个独立的组件(拥有自身的发布周期,且不同版本的核心组件之间通常不兼容)。

不足之处是,关于单独使用与直接配置 Metro/WSIT 的信息非常稀少(相对于与 NetBeans IDE 和 Glassfish 应用程序服务器联合使用的相关信息)。许多必须的信息仅仅在博客文章和电子邮件中进行记录(参见 参考资料 )。

接下来的 Java Web 服务 文章将继续讨论 Metro,下次的关注点是它的性能。与 Axis2 相比,Metro 在简单的消息交换中和使用 WS-Security 时的性能如何。

下载

描述 名字 大小 下载方法
本文源代码 j-jws10.zip 38KB HTTP


原文:http://www.ibm.com/developerworks/cn/java/j-jws10.html

分享到:
评论

相关推荐

    metro-jax-ws-jaxws221x.zip

    总之,“metro-jax-ws-jaxws221x.zip”是一个宝贵的资源,对于想要学习和掌握JAX-WS的开发者来说,它可以提供一个完整的实践环境,帮助理解Web服务的生命周期、客户端和服务端的交互以及如何在实际项目中应用JAX-WS...

    web 服务-- 理解 WS-Policy1

    在实际应用中,如Axis2、Metro和CXF这样的Java Web服务框架支持WS-Policy的配置,以便在服务接口的WSDL文档中定义策略。 在使用WS-Policy时,开发者应确保策略表达式的正确构造,并且遵循标准形式,以便于解析和...

    ws-exemplo:Glassfish Metro的JAX-WS示例

    4. **WS-*标准支持**:支持一系列Web服务扩展,如WS-Addressing、WS-Policy、WS-Security等。 5. **工具集**:提供了一套完整的开发工具,如wsimport和wsgen,用于生成服务端和客户端代码。 6. **部署灵活性**:可以...

    JAX-WS 2.2 Jar包

    - **WS-Security**:支持WS-Security标准,提供安全的Web服务通信,包括数字签名和加密。 - **MTOM(Message Transmission Optimization Mechanism)**:优化大文件传输,通过二进制传输而不是XML编码来提高效率。 -...

    Axis2与CXF的对比

    - 在没有WS-Security的情况下,Axis2、Metro和CXF的性能相近,主要取决于XML数据转换的速度。CXF和Metro使用JAXB,而Axis2使用ADB,但三者表现相当。 - 当涉及到WS-Security时,性能差距显现。在响应较少的场景...

    jbossws-metro-3.3.1.GA.zip

    此外,它还支持WS-Security、WS-Policy等高级Web服务功能,提供安全性和互操作性。 总之,jbossws-metro-3.3.1.GA.zip是JBoss ESB的重要组件,它提供了强大的Web服务支持,使得开发和部署基于Java EE的应用变得更加...

    webservice之jax-ws

    开发者可以使用诸如Apache CXF、Metro等开源框架来支持JAX-WS的开发,这些框架提供了更多的功能,如WS-Security、WS-Policy等扩展,同时简化了开发过程。 8. **示例** 在提供的链接...

    JAX-WS之旅(一)

    - **WS-Security**:提供Web服务安全标准,如数字签名和加密。 - **WS-ReliableMessaging**:确保消息传递的可靠性和顺序。 - **WS-Addressing**:处理Web服务的寻址问题。 **7. 结论** JAX-WS为Java开发者提供了...

    metro user guide

    Metro支持多种安全模型,如SSL/TLS加密、WS-Security、WS-SecureConversation等,确保数据传输的安全性。同时,它也支持基于证书的身份验证和授权机制。 7. **高级特性**:除了基本功能,Metro还提供了高级特性,如...

    jax-ws基于web容器发布webServer

    10. **安全性**:可能讨论了Web服务的安全性,如HTTPS、WS-Security等。 综上所述,这个主题涵盖了从创建、部署到测试JAX-WS Web服务的整个流程,对理解Java企业级应用中的Web服务交互具有重要意义。

    JAX-WS之旅(二)

    9. **安全与认证**: JAX-WS可以通过SSL/TLS加密、WS-Security、WS-Trust等标准实现Web服务的安全性,确保数据传输的机密性和完整性。 10. **工具支持**: 开发者可以使用诸如Apache CXF、Metro等JAX-WS实现工具,...

    jaxws java webservice需要的jar包

    6. **metro-config.jar** 和 **metro-utils.jar**:这部分是Metro框架的一部分,它是JAX-WS RI的扩展,提供了一些额外的功能,如WS-I兼容性、WS-Security等。 7. **stax-api.jar** 和 **woodstox-core-asl.jar**:...

    Project Tango: An Overview

    - **安全性**:支持WS-Security标准,为Web服务提供安全的消息交换。 - **事务处理**:支持WS-AtomicTransaction和WS-Cordination等规范,以确保跨多个服务的事务一致性。 - **互操作性**:与.NET 3.0的互操作性,...

    web service学习笔记1

    4. WS-I(Web Services Interoperability Organization)规范族,包括WS-Security、WS-RM、WS-Transaction、WS-Addressing等,确保遵循WS-Policy的Web服务特性实现跨平台互操作性。 Java语言对SOAP-based Web ...

    jaxws-ri.rar

    5. **wsit.jar**:Web Services Interoperability Technology (WSIT) 提供了额外的Web服务互操作性功能,如WS-Security、WS-Addressing等高级协议的支持。 6. **stax-api.jar** 和 **woodstox-core-asl.jar**:这些...

    使用安全验证的JAX-WS WEB SERVICES示例

    标题中的“使用安全验证的JAX-WS WEB SERVICES示例”指的是通过Java API for XML Web Services(JAX-WS)创建具有安全验证功能的Web服务。JAX-WS是Java平台上的一个标准,用于构建和消费基于SOAP的Web服务。在开发...

    JavaWebServicesUpAndRunning.chm

    此外,书中可能还涉及到了WS-Security(Web服务安全)、WS-I(Web服务互操作性)规范,这些对于确保Web服务的安全性和跨平台兼容性至关重要。WS-Security提供了身份验证、加密和消息完整性保护等功能,而WS-I则确保...

    (英文)Programming.WebLogic.Web.Services1

    6. **高级特性**:可能涉及WS-Security(Web服务安全)、WS-Policy(Web服务策略)等进阶主题,这些特性允许开发者实现安全的、符合特定策略的Web服务交互。 7. **性能优化**:讨论如何调整WebLogic Server的配置以...

    cxf 源码 java websevice

    4. **WS-*支持**:CXF实现了WS-Security、WS-ReliableMessaging、WS-Addressing等WS-*家族的标准,为Web服务提供了安全、可靠性和管理性。 5. **互操作性**:CXF的强项之一是其良好的互操作性,它可以与其他Web服务...

    JDK1.6支持WebService

    8. **Web服务安全**:JDK 1.6还提供了对WS-Security的支持,允许开发者实现身份验证、加密、签名等功能,保障Web服务的安全性。 综上所述,JDK 1.6对Web服务的支持使得Java开发者能够无缝地集成Web服务到他们的应用...

Global site tag (gtag.js) - Google Analytics