0% found this document useful (0 votes)
46 views15 pages

J jws13 PDF

The document discusses how to use WS-Security with the Apache CXF web services stack. It provides two examples - a simple UsernameToken example using plain text username and password, and an example using signing and encryption with X.509 certificates and keys. The document compares CXF's implementation of WS-Security to Axis2 and Metro, and shows how to configure WS-Security on the CXF client and server sides.

Uploaded by

Snig Kav
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views15 pages

J jws13 PDF

The document discusses how to use WS-Security with the Apache CXF web services stack. It provides two examples - a simple UsernameToken example using plain text username and password, and an example using signing and encryption with X.509 certificates and keys. The document compares CXF's implementation of WS-Security to Axis2 and Metro, and shows how to configure WS-Security on the CXF client and server sides.

Uploaded by

Snig Kav
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Java web services: WS-Security with CXF

See how to use WS-Security with the Apache CXF web services
stack

Dennis Sosnoski 23 March 2010


Architecture Consultant and Trainer
Sosnoski Software Solutions, Inc.

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 simple UsernameToken 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.

© Copyright IBM Corporation 2010 Trademarks


Java web services: WS-Security with CXF Page 1 of 15
developerWorks® ibm.com/developerWorks/

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"

Java web services: WS-Security with CXF Page 2 of 15


ibm.com/developerWorks/ developerWorks®

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">

Java web services: WS-Security with CXF Page 3 of 15


developerWorks® ibm.com/developerWorks/

<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 generated javax.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 the
javax.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.

Java web services: WS-Security with CXF Page 4 of 15


ibm.com/developerWorks/ developerWorks®

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">

Java web services: WS-Security with CXF Page 5 of 15


developerWorks® ibm.com/developerWorks/

<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 the
javax.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;
}
}
}
}

Java web services: WS-Security with CXF Page 6 of 15


ibm.com/developerWorks/ developerWorks®

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 (see Resources). 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>

Java web services: WS-Security with CXF Page 7 of 15


developerWorks® ibm.com/developerWorks/

<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">

Java web services: WS-Security with CXF Page 8 of 15


ibm.com/developerWorks/ developerWorks®

<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 simple UsernameToken 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"/>

Java web services: WS-Security with CXF Page 9 of 15


developerWorks® ibm.com/developerWorks/

<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");
}

Java web services: WS-Security with CXF Page 10 of 15


ibm.com/developerWorks/ developerWorks®

}
}
}
}

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 a java.util.Properties as the value for the ws-
security.encryption.properties key in the request context. (See the Listing 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.

Java web services: WS-Security with CXF Page 11 of 15


developerWorks® ibm.com/developerWorks/

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 the UsernameToken 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 web services: WS-Security with CXF Page 12 of 15


ibm.com/developerWorks/ developerWorks®

Downloads
Description Name Size
Source code for this article j-jws13.zip 28KB

Java web services: WS-Security with CXF Page 13 of 15


developerWorks® ibm.com/developerWorks/

Resources
Learn

• Apache CXF: Visit the site for CXF, an open source web services stack from the Apache
Software Foundation.
• WSS4J: WSS4J is the open source implementation of WS-Security from the Apache
Software Foundation. Both Axis2 and CXF use this library for their WS-Security processing.
• Understanding Web Services specifications: This series of tutorials introduces many of the
important Web services standards, including:
• "Understanding Web Services specifications: Web Services Description Language
(WSDL)" (Nicholas Chase, developerWorks, July 2006)
• "Understanding Web Services specifications: WS-Security" (Nicholas Chase,
developerWorks, August 2006)
• "Understanding Web Services specifications: WS-Policy" (Tyler Anderson,
developerWorks, February 2007).
• OASIS Web Services Security (WSS) TC: This is the organization responsible for the WS-
Security specification and token profiles. You can find links here to all versions of these
standards.
• The W3C Web Services Policy Working Group: This group defines the WS-Policy
specification.
• OASIS Web Services Secure Exchange (WS-SX) TC: This organization is responsible for
WS-SecurityPolicy and related specifications.

Get products and technologies

• CXF: Download CXF.


• Download IBM product evaluation versions or explore the online trials in the IBM SOA
Sandbox and get your hands on application development tools and middleware products from
DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.

Discuss

• Apache CXF mailing lists: Subscribe or browse the archives.


• Get involved in the My developerWorks community.

Java web services: WS-Security with CXF Page 14 of 15


ibm.com/developerWorks/ developerWorks®

About the author


Dennis Sosnoski

Dennis Sosnoski is a consultant and trainer specializing in Java-based XML and Web
services. His professional software development experience spans more than 30
years, with the last 10 focused on server-side XML and Java technologies. Dennis
is the lead developer of the open source JiBX XML Data Binding framework and the
associated JiBX/WS Web services framework, as well as a committer on the Apache
Axis2 Web services framework. He was also one of the Expert Group members for
the JAX-WS 2.0 and JAXB 2.0 specifications. The material for the Java Web Services
series is based on Dennis' training classes.

© Copyright IBM Corporation 2010


(www.ibm.com/legal/copytrade.shtml)
Trademarks
(www.ibm.com/developerworks/ibm/trademarks/)

Java web services: WS-Security with CXF Page 15 of 15

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy