`

Java web services: WS-Security with CXF (转)

 
阅读更多

This article is refered from  http://www.ibm.com/developerworks/java/library/j-jws13/index.html

 

Summary:  The Apache CXF web services stack supports WS-Security, including using WS-SecurityPolicy to configure the security handling. CXF is flexible in how you configure the deployment parameters used at run time to implement the security handling, supporting both static and dynamic configuration options for the client side. In this article, Java web services series author Dennis Sosnoski shows how to use CXF for both a simpleUsernameToken WS-Security example and one using signing and encryption.

View more content in this series

 

Like the Axis2 and Metro web services stacks discussed in earlier articles of this series, Apache CXF (which you met in "Introducing CXF") supports use of the WS-Security SOAP extension technology to provide a full range of security-related functions for message exchanges. Similar to these other stacks, CXF uses WS-SecurityPolicy to configure WS-Security handling (though manual configuration is also possible).

CXF's implementation of WS-Security is based on the open source WSS4J library (see Resources). This is the same library used by the Axis2 code, and consequently some of the WS-Security configuration details are similar between the two stacks. The layer of code that interprets WS-SecurityPolicy to configure WSS4J is different, though. In Axis2 it is handled by the separately distributed Rampart module, whereas in CXF it's handled by the cxf-rt-ws-policy and cxf-rt-ws-security modules (included in the standard cxf-#.jar, where # is the version number).

In this article, you'll see two examples of configuring WS-Security handling in CXF. The first is a simple UsernameToken that just wraps a plain-text username and password. The second example both signs and encrypts messages, using X.409 certificates and keys. These examples match those used with Axis2 in "Axis2 WS-Security basics" and "Axis2 WS-Security signing and encryption," and with Metro in "WS-Security with Metro," so you can compare techniques to see the differences among the stacks. See Download to obtain this article's sample code.

Configuration basics

About this series

Web services are a crucial part of Java technology's role in enterprise computing. In this series of articles, XML and web services consultant Dennis Sosnoski covers the major frameworks and technologies that are important to Java developers using web services. Follow the series to stay informed of the latest developments in the field and be aware of how you can use them to aid your programming projects.

WS-SecurityPolicy security configurations detail the security processing needed for messages being exchanged between a client and service. In most cases, the web services stack also requires some additional information to apply the security to a message exchange. For instance, a WS-SecurityPolicy may require the client to sign request messages sent to the server, providing nonrepudiation for the service. In this case, the client web services stack needs some way of identifying the specific private key to be used for signing when sending a message to the service.

Both Axis2 and Metro use custom WS-SecurityPolicy extensions to provide security parameters of this type. Since the WS-SecurityPolicy is normally embedded in a WSDL service description, you generally need to modify the WSDL document to add these details (though Axis2 allows you to set a policy directly in client code, as an alternative). This need to modify the WSDL document is both cumbersome and somewhat contrary to WSDL's intent, which is to serve as a service description.

CXF takes a different approach — or perhaps that should be different approaches — since there are multiple ways to configure CXF with the added parameters needed when applying a WS-SecurityPolicy configuration to messages. On the client side, you can do this either directly in client code or by using a Spring XML configuration file. On the server side, you always need to use an XML configuration file, though you still can choose among different types of files. You'll see how these alternatives for both client and server work in this article's examples.

UsernameToken in CXF

UsernameToken provides a standard way of representing a username and password pair with WS-Security. The password information can be sent as plain text (normally only used in production when combined with Transport Layer Security [TLS] or WS-Security encryption, but convenient for testing) or as a hash value. Besides being useful for many applications that want to require direct authentication, UsernameToken is the simplest form of WS-Security feature and makes a great starting point for examples.

To implement a simple plain-text UsernameToken example on CXF, you need a WSDL service definition with the appropriate WS-Policy/WS-SecurityPolicy configuration included. Listing 1 shows an edited version of the same basic WSDL service definition used in "Introducing CXF." Listing 1 includes policy information to require UsernameToken on requests from the client to the server. The policy reference in the <wsdl:binding> is shown in bold, as is the policy itself.


Listing 1. Plain-text 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/">
  
  <!-- Policy for UsernameToken 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"
      xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <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 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="CXFLibrary">

    <wsdl:port binding="wns:LibrarySoapBinding" name="library">
      <wsdlsoap:address location="http://localhost:8080/cxf-library-username"/>
    </wsdl:port>

  </wsdl:service>


</wsdl:definitions>

There's one significant difference between the Listing 1 WSDL and that used for UsernameToken in the Axis2 and Metro examples. This version includes an empty <sp:TransportBinding/> element as part of the WS-SecurityPolicy, which is necessary because of a bug in the CXF 2.2.6 release used for this article. Without a <sp:TransportBinding/>, or some form of encryption or signing, CXF's WS-SecurityPolicy handling couldn't process the UsernameToken. This error should be corrected in CXF versions later than 2.2.6.

The Listing 1 WSDL tells anyone who wants to access the service what needs to be done in terms of the security handling. As mentioned earlier, to use a policy you generally need to provide additional parameters to CXF. In this case, those parameters are the username and password for the client code to use when sending a request, and a means for validating a username and password on the server side when receiving a request. Next I'll show you examples of how you provide this additional information for each side of the exchange.

Client-side usage

Configuring CXF client WS-Security support can be handled either dynamically in client code or statically in configuration files.Listing 2 shows an example of UsernameToken dynamic configuration in client code:


Listing 2. UsernameToken dynamic configuration in client code
// 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");

A JAX-WS client uses a generated proxy interface to access a service. In the Listing 2 code, this is the Library interface. You create an instance of the interface (called a stub in the example code) by calling a method on the generatedjavax.xml.ws.Service subclass — in this case, the CXFService class. Although it's not reflected in the API of the generated code, JAX-WS guarantees that the returned proxy interface instance is always a subclass of thejavax.xml.ws.BindingProvider class. To configure CXF dynamically, you need to make use of this implied typing and cast the proxy to the BindingProvider class, then access the request context property map through that cast. Listing 2 shows how you can set the username and password for WS-Security handling in this property map.

Static configuration uses the same property values as the dynamic configuration, just set in a different way. CXF checks for a configuration file in the classpath on startup and, if it finds the file, uses it to set property values. By default, the configuration file must be named cxf.xml and be in a root directory of the classpath (though you can change this default by using a system property, cxf.config.file.url). Listing 3 shows an example of a cxf.xml file (present in the download code as cxf-username-client.xml), which can be used in place of the dynamic configuration shown in Listing 2:


Listing 3. UsernameToken static configuration in cxf.xml 
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jaxws="http://cxf.apache.org/jaxws"
   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>

The static configuration approach can be convenient when you're using fixed values for WS-Security parameters. You do need to be careful about the configuration file name and placement in the classpath, since the file is optional and CXF will operate without complaint if the file is not found (until it fails when trying to use WS-Security without the required parameters). If you do run into problems, you can check the INFO-level logging output by the client. You should see a message INFO: Loaded configuration file cxf.xml. (or other file name set using the cxf.config.file.url system property); if you don't see the message, the file was not found and you need to look to your classpath to find the cause.

Server-side usage

On the server side, you must use a configuration file for your WS-Security parameters. The simplest way of doing this is to add the information to the cxf-servlet.xml file that defines the service endpoint. Listing 4 shows a modified version of the cxf-servlet.xml used in the "Introducing CXF," with the added WS-Security information shown in bold (present in the download code as server/etc/cxf-username-servlet.xml):


Listing 4. cxf-servlet.xml with added security parameters
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:soap="http://cxf.apache.org/bindings/soap"
    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>

The added configuration information for this UsernameToken case is just a security callback class. This is the same approach used in the Axis2 and Metro examples, wherein the WS-Security code calls a user-supplied callback class implementing thejavax.security.auth.callback.CallbackHandler interface with the username and password information. The callback class can implement any type of handling you want to use to verify the combination of username and password, so it's a technique that allows maximum flexibility.

Listing 5 shows the callback class used by the example code. This class includes handling for both the UsernameToken case of verifying a username and password and the case of using signing and encryption (discussed in this article's next main section).


Listing 5. Server-side callback class
**
 * 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;
      }
    }
  }
}


As an alternative to using the default cxf-servlet.xml, you can configure a different file for server-side configuration in the web application's web.xml file. This approach is a little more complex to implement, since you must directly specify each CXF module you're going to use on the server, but it does allow a faster startup of the web application. See the CXF documentation "Configuration" page for details, under the "Server configuration files" topic.

Building and running the sample code

Before you can try out the sample code, you need to download and install a current version of CXF on your system (seeResources). You also need to edit the build.properties file in the root directory of the unzipped sample-code download to change the value of the cxf-home property to the path to your CXF installation. If you're going to be testing with a server on a different system or port, you may also want to change the host-name and host-port.

To build the sample application using the supplied Ant build.xml, open a console to the root directory of the download code and type ant. This will first invoke the CXF WSDLToJava tool to generate JAX-WS 2.x service classes and JAXB 2.x data model classes, then compile the client and server, and finally package the server code as a WAR. You can then deploy the generated cxf-library-username.war file to your test server, and finally type ant run on the console to try running the sample client. The sample client runs through a sequence of several requests to the server, printing brief results for each request.

Signing and encrypting in CXF

UsernameToken's simplicity makes it a good starting point, but it isn't a typical use of WS-Security. Most often, either signatures or encryption, or both, will be involved when you use WS-Security. Listing 6 shows an edited example of WSDL using both signatures and encryption (based on the examples from "WS-Security with Metro" and the earlier "Axis2 WS-Security signing and encryption." See the Axis2 article for a more-detailed discussion of signing and encrypting in general and for details of generating and using self-signed certificates for WS-Security). The policy portions of the WSDL are shown in bold.


Listing 6. Signing/encrypting 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/">
  
  <!-- 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-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=".../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
            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: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 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="CXFLibrary">

    <wsdl:port binding="wns:LibrarySoapBinding" name="library">
      <wsdlsoap:address location="http://localhost:8080/cxf-library-signencr"/>
    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

The only significant difference between the Listing 6 WSDL and that used in the earlier articles is that the WS-Policy/WS-SecurityPolicy portion has been moved to the start of the WSDL, in keeping with the most recent versions of the WSDL 1.1 schema definition.

Using private key-certificate pairs for signing and encrypting messages is more complex to configure than the simpleUsernameToken example. You need to identify key stores as the sources of the keys and certificates, and also provide the passwords needed to access keys from the stores. The key store information must be provided by a .properties file; the password used for access to a private key must be supplied by a callback. Next, you'll see how this works for both client and server.

Client-side usage

Just as in the UsernameToken example, you can configure the security parameters needed for signing and encrypting messages either directly in your client code or by using a cxf-client.xml configuration file. Listing 7 shows a cxf-client.xml used for this purpose (cxf-signencr-client.xml in the download sample code):


Listing 7. cxf-client.xml with signing and encrypting parameters
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jaxws="http://cxf.apache.org/jaxws"
   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>

The Listing 7 cxf-client.xml defines two pairs of properties file and usernames, one pair for use in signature processing and the other for use in encryption processing. Each properties file identifies a key store and provides access information for that store. The associated username value identifies the key (for signing) or certificate (for encryption) within that store to be used for processing. In this case, the signature processing and the encryption processing use the same key store, which contains both the server certificate and the client private key and certificate. Since there's only one store, both properties reference the same client-crypto.properties file. This file, which must be present in a root directory of the classpath, is shown in Listing 8:


Listing 8. client-crypto.properties file
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

The Listing 8 properties file is used by the underlying WSS4J WS-Security code to configure the signature and encryption processing. It identifies the "provider" used to handle signature and encryption processing, the type of key store, the key store password, and the key store file (which must be present in a root directory of the classpath).

Besides the key store information, the Listing 7 cxf-client.xml file defines one other parameter — ws-security.callback-handler, previously seen in the Listing 4 cxf-servlet.xml. As in the previous example, the value for this parameter must be a security callback handler class. The WSS4J code will call a instance of this class when it needs to access the password used to secure the client private key within the key store. The implementation used in the sample code is shown in Listing 9:


Listing 9. Client-side callback class
/**
 * 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");
         }

      }
    }
  }
}

Just as in the UsernameToken example, you can configure the security parameters in your client code as an alternative to using a cxf-client.xml file. You can even replace the Listing 8 properties file with values you construct in code, setting ajava.util.Properties as the value for the ws-security.encryption.properties key in the request context. (See theListing 2 example of setting the username and password properties in the context.)

Server-side usage

On the server side, you need to include basically the same security parameters as supplied for the client in your cxf-servlet.xml file. Listing 10 shows the modified cxf-servlet.xml used in the example code (where you can find it as server/etc/cxf-signencr-servlet.xml), with the added WS-Security parameters shown in bold:


Listing 10. cxf-servlet.xml with added security parameters
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:soap="http://cxf.apache.org/bindings/soap"
    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>

The main differences from the client settings are that this server version doesn't specify an encryption properties file, and the encryption username setting is useReqSigCert. This value is a special name recognized by WSS4J to mean that the client certificate used to sign the request should be used to encrypt the response. Using this setting allows the server code to work with multiple clients, each having its own certificate.

The server-crypto.properties file is essentially identical to the client-crypto.properties shown in Listing 8. The server callback class is the same one as in the UsernameToken example, shown in Listing 5.

Building and running the sample code

For the signing and encrypting example, you need to change the build.properties file to use variant-name=signencr (rather than the username value for the UsernameToken example). Other than that, you follow the same build steps as in theUsernameToken example.

If you run the client using the current 2.2.6 version of CXF, you'll see some WARNING-level logging output, for example WARNING: No assertion builder for type ... registered. These messages do not indicate any problems in the code and will probably be eliminated in later versions of CXF.

Conclusion

In this article, you've seen how to use WS-Security with CXF. Like Axis2 and Metro, CXF supports WS-SecurityPolicy in WSDL as a standard approach to WS-Security configuration. Depending on your application needs, you can configure the additional required security parameters in several ways, without embedding deployment information in the service WSDL. In this respect, CXF is easier and cleaner to use for WS-Security than Axis2 and Metro.

Testing the example code for this article showed one bug in CXF, which is being fixed. This bug causes the UsernamePolicy to be ignored unless some other form of security processing is also required by the policy. It's hard to judge the robustness of the CXF WS-SecurityPolicy handling based on the simple examples used in this article, but the design seems sound and it's likely that as more people make use of this relatively new feature of CXF, any quirks in the implementation will be resolved quickly.

The next Java web services installment continues with CXF, this time looking at performance. See how CXF performance compares to the latest Axis2 and Metro releases, both for simple message exchanges and with WS-Security in use.

分享到:
评论

相关推荐

    纯java调用ws-security+CXF实现的webservice安全接口

    CXF是一个开源的服务框架,它允许开发人员创建和消费各种Web服务,而ws-security(Web Services Security)则是用于保护Web服务的标准。 首先,我们要理解ws-security的概念。它是 Oasis Web服务安全技术委员会制定...

    Web 服务规范_第 4 部分:WS-Security源码

    这一规范的第4部分,WS-Security(Web Services Security),是其中的关键组件,它专注于提供Web服务的安全性,确保通信过程中的数据完整性和机密性。本文将深入探讨WS-Security源码的实现原理和关键功能。 WS-...

    ws-security 和wss4j的jar包

    而Apache WSS4J(Web Services Secure Utilities for Java)则是Apache软件基金会开发的一个实现WS-Security标准的开源库,它为Java开发者提供了处理和验证Web服务消息安全性的工具。 首先,我们来看一下标题提到的...

    ws-security jar

    【标题】"ws-security jar" 是一个与Web服务安全相关的Java库,主要用于实现Web服务的安全标准,如WS-Security(Web Services Security)。在Web服务的世界里,安全性是至关重要的,因为它们经常涉及到跨网络的数据...

    ws-security java-mail

    首先,`ws-security`(Web Services Security)是 Oasis Web Services Security Technical Committee 开发的一套标准,用于增强基于SOAP的消息的安全性。它提供了认证、授权、消息完整性以及消息机密性的解决方案。...

    Java Web Services: up and running

    1. **JAX-WS**:Java API for XML Web Services,它是Java平台上的标准,用于创建面向服务的架构(SOA)中的Web服务。JAX-WS允许开发者使用注解将方法映射到Web服务操作,简化了服务的创建。 2. **SOAP**:简单对象...

    cxf+ws-security-JAR

    【描述】该描述指出,这个项目是关于如何使用Apache CXF,一个开源的Java框架,来构建和部署SOAP Web服务,并且结合WS-Security标准进行安全增强。WS-Security(Web Services Security)是一种用于保护Web服务通信的...

    ws-security三个jar包

    例如,使用Apache CXF或Java的JAX-WS API时,可以配置WS-Security处理器来处理这些安全特性。 总结起来,"ws-security三个jar包"是实现Web服务安全的关键组件,它们提供了WS-Security规范所定义的多种安全功能,如...

    我的cxf与ws-security

    【标题】"我的cxf与ws-security"涉及的是在Java Web服务开发中使用Apache CXF框架集成WS-Security(Web Service Security)的安全机制。Apache CXF是一个开源的、功能丰富的Web服务框架,它允许开发者创建和消费各种...

    CXF WS-Security WSS4J 例子

    在CXF中,WS-Security(Web Services Security)是一种关键的安全机制,用于确保Web服务的安全通信。WSS4J(Web Services Security for Java)是Apache的开源库,它为Java应用程序提供了实施WS-Security标准的功能。...

    CXF(WS_Security)证书加密

    WS-Security(Web Services Security)是一种标准,定义了如何在SOAP消息中添加安全信息,如数字签名、加密等,以确保消息的完整性和机密性。WS-Security是OASIS(Organization for the Advancement of Structured ...

    apache-cxf-2.7.7以及cxf客户端所需要的jar包

    它支持Java语言的JAX-WS(Java API for XML Web Services)和JAX-RS(Java API for RESTful Web Services)标准,同时兼容Spring框架,使得集成到现有的企业应用体系中更为便捷。 首先,Apache CXF的核心组件包括:...

    apache-cxf-3.1.6所有jar包

    1. **JAX-WS**:Java API for XML Web Services,是Java平台上的Web服务规范,CXF提供了对JAX-WS的全面支持,使得开发者能够轻松地创建、部署和消费SOAP服务。 2. **JAX-RS**:Java API for RESTful Web Services,...

    最新版CXF的jar包

    - `cxf-rt-ws-security.jar`:包含Web服务安全相关的类。 - `cxf-rt-rs-extension-providers.jar`:用于RESTful服务的扩展提供者。 这些jar包组合在一起,构成了一个完整的CXF运行环境,可以帮助开发者快速构建和...

    CXF开发所需jar包

    对于需要安全性的Web服务,如WS-Security,CXF提供了相应的jar包,如`cxf-rt-ws-security.jar`,包含了加密、签名、认证等安全功能。 6. **数据绑定和对象映射**: CXF支持多种数据绑定技术,如JAXB(Java ...

    web-services-with-java.zip_java web

    7. **Web服务安全**:包括WS-Security(Web Services Security)、OAuth和JWT(JSON Web Token)等标准,用于保护Web服务免受未经授权的访问。在Java中,Spring Security可以集成到Web服务项目中,提供身份验证和...

    apache-cxf-2.4.1.rar_apache-cxf-2.4.1_cxf_web service

    1. **Web服务支持**:CXF支持多种Web服务标准,如SOAP、RESTful API、WS-*(包括WS-Security、WS-ReliableMessaging等)、JAX-RS(Java API for RESTful Web Services)和JAX-WS(Java API for XML Web Services)。...

    webservice apache-cxf-3.0.7 jar包

    - `cxf-rt-ws-security.jar`:WS-Security模块,实现安全相关的Web服务功能。 - `cxf-tools-wsdlto.jar`:WSDL工具,用于生成Java代码和服务。 - `cxf-xjc-utils.jar`:XJC工具,用于处理JAXB相关的XML到Java转换。 ...

    apache-cxf-2.7.5所有jar都在

    - **cxf-rt-frontend-jaxrs**: 提供JAX-RS(Java API for RESTful Web Services)的支持。 - **cxf-rt-transports-http**和**cxf-rt-transports-http-jetty**: HTTP和Jetty传输实现。 - **cxf-rt-bindings-soap**和*...

    Java-Web-Services-in-a-Nutshell.rar_out

    1. **Java Web服务定义**:Java Web服务是一种基于开放标准(如XML、WSDL、SOAP和UDDI)的编程模型,使得不同平台的应用程序能够相互通信。Java平台提供了全面的工具和API来开发、部署和使用Web服务。 2. **SOAP...

Global site tag (gtag.js) - Google Analytics