Java Web服务:通过CXF使用WS-Security

日期: 2010-04-25 作者:Dennis Sosnoski 来源:TechTarget中国 英文

  Apache CXF支持使用WS-Security SOAP扩展技术提供一整套用于消息交换的与安全相关的功能。与这些堆栈一样,CXF也使用WS-SecurityPolicy配置 WS-Security 安全处理(也可以手工配置)。

  CXF的WS-Security实现基于开放源码的WSS4J库。Axis2代码也使用这个库,因此这两个堆栈的WS-Security配置细节有一些相似之处。但是,通过解释WS-SecurityPolicy配置WSS4J的代码层不一样。在Axis2中这由单独发布的Rampart模块处理,而在CXF中由cxf-rt-ws-policy和cxf-rt-ws-security模块处理(这些模块包含在标准的cxf-#.jar中,其中的#是版本号)。

  在本文中,您会看到在CXF中配置WS-Security处理的两个示例。第一个示例是一个简单的UsernameToken,它仅仅包装明文用户名和密码。第二个示例使用X.409证书和密钥对消息进行签名和加密。这些示例与 “Axis2 WS-Security基础” 和 “Axis2 WS-Security 签名和加密” 中通过Axis2和Metro实现的示例一致,这样您就可以看出这些堆栈的技术差异。

  配置基础

  关于本系列Web服务构成了Java技术在企业计算应用中的关键部分。在本系列文章中,XML和Web服务顾问Dennis Sosnoski介绍对于使用 Web服务的Java开发人员来说比较重要的主要框架和技术。通过跟随本系列学习,您将了解到该领域的最新进展,并且知道如何使用它们来为您的编程项目提供帮助。

  WS-SecurityPolicy安全配置指定在客户机和服务之间交换的消息所需的安全处理。在大多数情况下,Web服务堆栈还需要更多信息,才能对消息交换应用安全措施。例如,WS-SecurityPolicy可能要求客户机对发送到服务器的请求消息进行签名,这为服务提供不可否认性。在这种情况下,在把消息发送到服务时,客户机Web服务堆栈需要通过某种方法确定用于签名的私有密钥。

  Axis2和Metro使用定制的WS-SecurityPolicy扩展提供这种安全参数。因为WS-SecurityPolicy通常嵌入在WSDL服务描述中,所以一般需要通过修改WSDL文档添加这些信息(Axis2也允许在客户机代码中直接设置策略)。修改WSDL文档很麻烦,而且违背WSDL的意图(即作为服务描述)。

  CXF采用不同的方法,可能应该说多种不同的方法,因为可以通过多种方法为CXF配置在对消息应用WS-SecurityPolicy配置时需要的参数。在客户端,可以直接在客户机代码中配置,也可以使用Spring XML配置文件。在服务器端,需要使用XML配置文件,但是仍然可以选择不同的文件类型。在本文的示例中,将演示客户机和服务器可以采用的不同方法。

  CXF中的UsernameToken

  UsernameToken是向WS-Security提供用户名和密码对的标准方法。可以以明文形式发送密码信息(通常只在与 Transport Layer Security [TLS] 或 WS-Security 加密结合使用时用于生产环境,但是便于测试),也可以以散列值形式发送。它对于需要直接身份验证的许多应用程序很方便。UsernameToken是WS-Security特性最简单的形式,很适合作为第一个示例。

  要想在CXF中实现简单的明文UsernameToken示例,需要一个 WSDL 服务定义,其中应该包含适当的WS-Policy/WS-SecurityPolicy配置。清单 1 给出 “CXF 简介” 中使用的基本WSDL服务定义经过编辑之后的版本。清单 1 包含的策略信息要求在客户机发送给服务器的请求中有 UsernameToken。<wsdl:binding> 中的策略引用和策略本身以粗体显示。


  清单 1. 明文UsernameToken WSDL
    

以下是引用片段:
<?xml version=”1.0″ encoding=”UTF-8″?> 
<wsdl:definitions targetNamespace=”http://ws.sosnoski.com/library/wsdl”
    
    
    
    >
  
  <!– Policy for UsernameToken with plaintext password, sent from client to
    server only –>
  <wsp:Policy wsu:Id=”UsernameToken” 
   >
   <wsp:ExactlyOne>
      <wsp:All>
        <!– Empty <TransportBinding/> element required due to bug in CXF 2.2.6 –>
        <sp:TransportBinding/>
        <sp:SupportingTokens>
          <wsp:Policy>
            <sp:UsernameToken sp:IncludeToken=”…/IncludeToken/AlwaysToRecipient”/>
          </wsp:Policy>
        </sp:SupportingTokens>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
  
  <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 
        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=”CXFLibrary”>
    <wsdl:port binding=”wns:LibrarySoapBinding” name=”library”>
      <wsdlsoap:address location=”http://localhost:8080/cxf-library-username”/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

 
  在 清单 1与Axis2和Metro示例使用的WSDL之间有一个重要的差异。这个版本的WS-SecurityPolicy配置中包含一个空的 <sp:TransportBinding/> 元素,这是因为本文使用的CXF 2.2.6中有一个bug。如果没有 <sp:TransportBinding/> 或某种形式的加密或签名,CXF的WS-SecurityPolicy处理就无法处理 UsernameToken。在高于2.2.6的CXF 版本中应该会纠正这个错误。

  清单 1 中的WSDL告诉要访问这个服务的任何客户机在安全处理方面需要做什么。正如前面提到的,要想使用策略,一般需要向CXF提供额外的参数。在这个示例中,参数是客户机代码在发送请求时使用的用户名和密码,还有服务器端在接收请求时检验用户名和密码的方法。下面的示例演示如何向消息交换的两端提供这些额外信息。

  客户端使用方法

  可以在客户机代码中动态地配置CXF客户机WS-Security支持,也可以在配置文件中静态地配置。清单2是在客户机代码中动态地配置UsernameToken的示例。

  清单 2. 在客户机代码中动态地配置UsernameToken 
    

以下是引用片段:
// create the client stub
CXFLibrary service = new CXFLibrary();
Library stub = service.getLibrary();

// set the username and password
Map ctx = ((BindingProvider)stub).getRequestContext();
ctx.put(“ws-security.username”, “libuser”);
ctx.put(“ws-security.password”, “books”);

 
  JAX-WS客户机使用生成的代理接口访问服务。在 清单2中,这是Library接口。通过调用生成的javax.xml.ws.Service的子类(在这里是 CXFService 类)的一个方法,创建接口的实例(在示例代码中称为stub)。尽管在生成的代码的API中没有反映出来,但是JAX-WS会保证返回的代理接口实例总是javax.xml.ws.BindingProvider类的子类。要想动态地配置CXF,需要使用这个隐含的类型并把代理转换为BindingProvider类,然后通过类型转换访问请求上下文属性映射。清单 2 演示如何在属性映射中为WS-Security处理设置用户名和密码。

  静态配置使用与动态配置相同的属性值,只是以不同的方法设置。CXF在启动时在类路径中寻找配置文件,如果找到了,就用它设置属性值。在默认情况下,这个配置文件必须名为cxf.xml,必须放在类路径的根目录中(但是可以使用系统属性cxf.config.file.url修改默认设置)。清单3给出一个cxf.xml文件示例(下载代码中的cxf-username-client.xml),可以用它替代 清单2所示的动态配置:

清单 3. 在cxf.xml中静态地配置UsernameToken 
    

以下是引用片段:
<beans 
   
   
   xsi:schemaLocation=”http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
   http://cxf.apache.org/jaxws 
   http://cxf.apache.org/schemas/jaxws.xsd”>
  <jaxws:client name=”{http://ws.sosnoski.com/library/wsdl}library”
      createdFromAPI=”true”>
    <jaxws:properties>
      <entry key=”ws-security.username” value=”libuser”/>
      <entry key=”ws-security.password” value=”books”/>
    </jaxws:properties>
  </jaxws:client>
</beans>
 
  如果要使用固定的WS-Security参数值,静态配置方法比较方便。必须确保配置文件的名称及其在类路径中的位置正确,因为这个文件是可选的,如果没有找到它,CXF 会继续运行,不会发出警告(直到它试图使用WS-Security时由于缺少所需的参数而失败)。如果遇到了问题,可以检查客户机的 INFO 级日志输出。应该会看到消息 INFO: Loaded configuration file cxf.xml.(或者通过cxf.config.file.url系统属性设置的其他文件名);如果没有 看到这个消息,就说明没有找到文件,需要检查类路径以查明原因。

  服务器端使用方法

  在服务器端,必须使用配置文件提供WS-Security参数。最简单的方法是把这些信息添加到定义服务端点的 cxf-servlet.xml 文件中。清单 4 给出 “CXF 简介” 中使用的cxf-servlet.xml经过修改之后的版本,添加的WS-Security信息以粗体显示(下载代码中的server/etc/cxf-username-servlet.xml):

  清单 4. 添加了安全参数的cxf-servlet.xml
    

以下是引用片段:
<?xml version=”1.0″ encoding=”UTF-8″?> 
<beans 
    
    
    
    xsi:schemaLocation=”http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
      http://cxf.apache.org/jaxws
      http://cxf.apache.org/schemas/jaxws.xsd”>
  <jaxws:endpoint id=”Processor”
      implementor=”com.sosnoski.ws.library.cxf.CXFLibraryImpl”
      wsdlLocation=”WEB-INF/wsdl/library-signencr.wsdl”
      address=”/”>
    <jaxws:properties>
      <entry key=”ws-security.callback-handler”
          value=”com.sosnoski.ws.library.cxf.ServerCallback”/>
    </jaxws:properties>
  </jaxws:endpoint>
</beans>

 
  为这个UsernameToken示例添加的配置信息是一个安全回调类。Axis2和Metro示例也使用这种方法。WS-Security代码用用户名和密码信息调用用户提供的回调类,这个类实现javax.security.auth.callback.CallbackHandler接口。这个回调类可以实现您需要的任何用户名和密码组合检验方法,所以这种技术非常灵活。

  清单 5 给出示例代码使用的回调类。这个类可以处理检验用户名和密码的UsernameToken示例,也可以处理使用签名和加密的示例(在本文的下一节中讨论)。


  清单 5. 服务器端回调类
    

以下是引用片段:
**
 * Simple password callback handler. This just handles two cases: matching the username
 * and password, and providing the password used for access to the private key.
 */
public class ServerCallback 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.getIdentifier();
      switch (pwcb.getUsage()) {
          case WSPasswordCallback.USERNAME_TOKEN_UNKNOWN:
              // used when plaintext password in message
              if (!”libuser”.equals(id) || !”books”.equals(pwcb.getPassword())) {
                    throw new UnsupportedCallbackException(callbacks[i], “check failed”);
                }
                break;
        case WSPasswordCallback.DECRYPT:
        case WSPasswordCallback.SIGNATURE:
              // used to retrieve password for private key
              if (“serverkey”.equals(id)) {
                    pwcb.setPassword(“serverpass”);
                }
                break;
      }
    }
  }
}

  也可以不使用默认的cxf-servlet.xml,而是在Web应用程序的web.xml文件中指定另一个文件来提供服务器端配置。这种方法比较复杂,因为必须直接指定在服务器上要使用的每个 CXF 模块,但是这会加快Web应用程序的启动速度。详细信息见CXF文档 “Configuration” 页面中的 “Server configuration files” 主题。

  构建并运行示例代码

  在运行示例代码之前,需要下载并在自己的系统上安装CXF的当前版本(见 参考资料)。还需要编辑解压后的 示例代码 的根目录中的 build.properties 文件,把cxf-home属性改为CXF的安装路径。如果打算用不同的系统上的服务器或不同的端口进行测试,还需要修改host-name和host-port。

  为了使用提供的Ant build.xml构建示例应用程序,打开一个控制台,进入下载代码的根目录,然后输入ant。这首先调用CXF WSDLToJava工具来生成JAX-WS 2.x服务类和JAXB 2.x数据模型类,然后编译客户机和服务器,最后把服务器代码打包为一个WAR。然后,可以把生成的cxf-library-username.war文件部署到测试服务器上,在控制台上输入ant run运行示例客户机。示例客户机向服务器发送几个请求,输出每个请求的简要结果。

  在CXF中实现签名和加密

  UsernameToken很简单,很适合作为起点,但这不是WS-Security的典型用法。在使用WS-Security时,往往会涉及签名和/或加密。清单 6 给出一个使用签名和加密的 WSDL 示例(基于前面的 “Metro 服务下的WS-Security”和“Axis2 WS-Security 签名和加密” 中的示例)。在 Axis2 文章中可以找到对签名和加密的详细讨论,以及为WS-Security生成和使用自签名证书的详细信息。WSDL的策略部分以粗体显示。

  清单 6. 签名/加密WSDL
    

以下是引用片段:
<?xml version=”1.0″ encoding=”UTF-8″?> 
<wsdl:definitions targetNamespace=”http://ws.sosnoski.com/library/wsdl”
    
    
    
    >
  
  <!– 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”
      
      >
  
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:AsymmetricBinding
            >
          <wsp:Policy>
            <sp:InitiatorToken>
              <wsp:Policy>
                <sp:X509Token sp:IncludeToken=”…/AlwaysToRecipient”>
                  <wsp:Policy>
                    <sp:RequireThumbprintReference/>
                  </wsp:Policy>
                </sp:X509Token>
              </wsp:Policy>
            </sp:InitiatorToken>
            <sp:RecipientToken>
              <wsp:Policy>
                <sp:X509Token sp: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
            >
          <sp:Body/>
        </sp:SignedParts>
        <sp:EncryptedParts
            >
          <sp:Body/>
        </sp:EncryptedParts>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
  
  <wsdl:types>
    …
  </wsdl:types>
  <wsdl:message name=”getBookRequest”>
    <wsdl:part element=”wns:getBook” name=”parameters”/>
  </wsdl:message>
  …
  
  <wsdl:portType name=”Library”>
    …
  </wsdl:portType>
  <wsdl:binding name=”LibrarySoapBinding” type=”wns:Library”>
  
    <wsp:PolicyReference 
        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=”CXFLibrary”>
    <wsdl:port binding=”wns:LibrarySoapBinding” name=”library”>
      <wsdlsoap:address location=”http://localhost:8080/cxf-library-signencr”/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

 
  清单 6 与前面文章中使用的WSDL之间只有一个显著的差异,WS-Policy/WS-SecurityPolicy部分转移到了WSDL的开头,与WSDL 1.1模式定义的最新版本保持一致。

  与简单的UsernameToken示例相比,使用私有密钥-证书对进行消息签名和加密的配置比较复杂。需要指定密钥存储作为密钥和证书的来源,还要提供访问密钥存储所需的密码。必须通过.properties文件提供密钥存储信息;必须通过回调提供用于访问私有密钥的密码。接下来,看看在客户机和服务器上的实现方式。

  客户端使用方法

  与UsernameToken示例一样,可以在客户机代码中直接配置消息签名和加密所需的安全参数,也可以使用cxf-client.xml配置文件。清单 7 给出用于签名和加密的cxf-client.xml(示例代码中的 cxf-signencr-client.xml):

  清单 7. 包含签名和加密参数的cxf-client.xml
    

以下是引用片段:
<beans 
   
   
   xsi:schemaLocation=”http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
   http://cxf.apache.org/jaxws 
   http://cxf.apache.org/schemas/jaxws.xsd”>
  <jaxws:client name=”{http://ws.sosnoski.com/library/wsdl}library”
      createdFromAPI=”true”>
    <jaxws:properties>
      <entry key=”ws-security.signature.properties”
          value=”client-crypto.properties”/>
      <entry key=”ws-security.signature.username” value=”clientkey”/>
      <entry key=”ws-security.encryption.properties”
          value=”client-crypto.properties”/>
      <entry key=”ws-security.encryption.username” value=”serverkey”/>
      <entry key=”ws-security.callback-handler”
          value=”com.sosnoski.ws.library.cxf.ClientCallback”/>
    </jaxws:properties>
  </jaxws:client>
</beans>

 
  清单 7 所示的cxf-client.xml定义了两对属性文件和用户名,一对用于签名处理,另一对用于加密处理。每个属性文件指定一个密钥存储并提供访问密钥存储所需的信息。相关联的用户名值指定存储中要使用的密钥(用于处理签名)或证书(用于处理加密)。在这里,签名处理和加密处理使用同一个密钥存储,其中包含服务器证书与客户机私有密钥和证书。因为只有一个存储,这两个属性引用同一个client-crypto.properties文件。这个文件必须放在类路径的根目录中,见 清单 8:

  清单 8. client-crypto.properties文件 
    

以下是引用片段:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin 
org.apache.ws.security.crypto.merlin.keystore.type=jks 
org.apache.ws.security.crypto.merlin.keystore.password=nosecret 
org.apache.ws.security.crypto.merlin.file=client.keystore

 
  底层的WSS4J WS-Security代码使用 清单 8 所示的属性文件配置签名和加密处理。它指定用来处理签名和加密的 “提供者”、密钥存储的类型、密钥存储密码和密钥存储文件(必须放在类路径的根目录中)。

  除了密钥存储信息之外,清单 7 中的 cxf-client.xml 文件还定义另一个参数 — ws-security.callback-handler,在前面的 清单 4 cxf-servlet.xml中见过这个参数。与前面的示例一样,这个参数的值必须是一个安全回调处理器类。当WSS4J代码需要访问密钥存储密码以获取客户机私有密钥时,它调用这个类的实例。示例代码中使用的实现见 清单 9:

  清单 9. 客户端回调类
    

以下是引用片段:
/**
 * Simple password callback handler. This just checks if the password for the private key
 * is being requested, and if so sets that value.
 */
public class ClientCallback implements CallbackHandler {
  public void handle(Callback[] callbacks) throws IOException {
    for (int i = 0; i < callbacks.length; i++) {
      WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
      String id = pwcb.getIdentifier();
      int usage = pwcb.getUsage();
      if (usage == WSPasswordCallback.DECRYPT || usage == WSPasswordCallback.SIGNATURE) {
         // used to retrieve password for private key
         if (“clientkey”.equals(id)) {
             pwcb.setPassword(“clientpass”);
         }
      }
    }
  }

  与UsernameToken示例一样,可以不使用cxf-client.xml文件,而是在客户机代码中配置安全参数。甚至可以把 清单 8 中的属性文件替换为在代码中构造的值,设置一个java.util.Properties,作为请求上下文中ws-security.encryption.properties键的值。(参见 清单 2 中以这种方式设置用户名和密码属性的示例。)

  服务器端使用方法

  在服务器端,需要在cxf-servlet.xml文件中包含与客户机基本相同的安全参数。清单 10 给出示例代码中使用的cxf-servlet.xml(示例代码中的 server/etc/cxf-signencr-servlet.xml),添加的WS-Security参数以粗体显示:

  清单 10. 添加了安全参数的cxf-servlet.xml 
    

以下是引用片段:
<?xml version=”1.0″ encoding=”UTF-8″?> 
<beans 
    
    
    
    xsi:schemaLocation=”http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
      http://cxf.apache.org/jaxws
      http://cxf.apache.org/schemas/jaxws.xsd”>
  <jaxws:endpoint id=”Processor”
      implementor=”com.sosnoski.ws.library.cxf.CXFLibraryImpl”
      wsdlLocation=”WEB-INF/wsdl/library-signencr.wsdl”
      address=”/”>
    <jaxws:properties>
      <entry key=”ws-security.signature.properties” value=”server-crypto.properties”/>
      <entry key=”ws-security.signature.username” value=”serverkey”/>
      <entry key=”ws-security.encryption.username” value=”useReqSigCert”/>
      <entry key=”ws-security.callback-handler”
          value=”com.sosnoski.ws.library.cxf.ServerCallback”/>
    </jaxws:properties>
  </jaxws:endpoint>
</beans>

 
  这个服务器版本与客户机设置的主要差异是,它没有指定加密属性文件,而且加密用户名设置是useReqSigCert。这个值是SS4J能够识别的特殊名称,这表示应该使用请求签名所用的客户机证书对响应进行加密。使用这个设置让服务器代码可以处理多个客户机,每个客户机有自己的证书。

  server-crypto.properties文件实际上与 清单 8 所示的client-crypto.properties相同。服务器回调类与 UsernameToken 示例中使用的相同,见 清单 5。

  构建并运行示例代码

  对于签名和加密示例,需要修改build.properties文件以使用variant-name=signencr(而不是UsernameToken示例使用的username值)。除此之外,构建步骤与UsernameToken示例相同。

  如果使用CXF当前的 2.2.6 版运行客户机,会看到某种 WARNING 级日志输出,例如 WARNING: No assertion builder for type … registered。这些消息并不意味着代码中有任何问题,在以后的 CXF 版本中可能不会出现。

  结束语

  在本文中,您了解了如何通过 CXF 使用 WS-Security。与Axis2和Metro一样,CXF支持在WSDL中设置WS-SecurityPolicy这种标准的WS-Security配置方法。根据应用程序的需要,可以以几种方法配置额外的安全参数,不需要把部署信息嵌入在服务WSDL中。因此,与Axis2和 Metro相比,CXF使用WS-Security的方法更简便更清晰。

  测试本文的示例代码时发现了CXF中的一个bug,这个bug正在纠正。它导致UsernamePolicy被忽略,除非这个策略也要求其他形式的安全处理。很难根据本文中的简单示例评价CXF WS-SecurityPolicy处理的健壮性,但是它的设计看起来是可靠的,很可能有越来越多的人使用这个相当新的CXF特性,实现中的问题会很快解决。

  Java Web服务 的下一期继续讨论CXF,这一次讨论性能问题。我要对比CXF与最新Axis2和Metro版本的性能,包括简单的消息交换和使WS-Security两种情况。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐