JBoss.orgCommunity Documentation

Chapter 5. JBossWS-StackCXFUserGuide

5.1. JBossWS CXF Integration
5.1.1. Creating a Bus instance
5.1.2. Server Side Integration Customization
5.2. Extended Features
5.2.1. WS-Addressing
5.2.2. WS-ReliableMessaging
5.2.3. WS-Policy
5.2.4. WS-Security
5.2.5. JMS transport
5.3. HTTP server transport setup
5.4. SOAP Message Logging

Note

This page covers features available in JBossWS CXF stack only. Please refer to the common user guide for a basic introduction to JAX-WS programming as well as documentation on all features, tools, etc. the JBossWS Web Service Framework provides for every supported stack (including CXF stack).

 

Also please note this page does not go through the documentation of every feature, option, etc. provided by Apache CXF; on the countrary the only topics covered here are specific issues regarding integration with JBoss and stack specific features provided by JBossWS Web Service Framework for the CXF stack. A few tutorials are also provided for show how to leverage some WS technologies.

The official Apache CXF documentation is available here.

 

It is possible to customize the JBossWS and CXF integration by incorporating the CXF configuration file to the endpoint deployment archive. In order for that to be possible, JBossWS-CXF requires Spring to be installed in the application server. The Spring Framework libraries installation can be perfomed using the JBossWS-CXF installation.

The convention is the following:

  • file name must be jbossws-cxf.xml

  • for POJO deployments it is located in WEB-INF directory

  • for EJB3 deployments it is located in META-INF directory

If user do not provide its own CXF configuration file, a default one is automatically generated during the deployment.

For POJO deployments the generated jbossws-cxf.xml has the following content:

<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://cxf.apache.org/jaxws
  http://cxf.apache.org/schemas/jaxws.xsd'>

  <!-- one or more jaxws:endpoint POJO declarations -->
  <jaxws:endpoint
    id='POJOEndpoint'
    address='http://localhost:8080/pojo_endpoint_archive_name'  
    implementor='my.package.POJOEndpointImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerJSE'/>
    </jaxws:invoker>
  </jaxws:endpoint></beans>

For EJB3 deployments the generated jbossws-cxf.xml has the following content:

<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://cxf.apache.org/jaxws
  http://cxf.apache.org/schemas/jaxws.xsd'>

  <!-- one or more jaxws:endpoint EJB3 declarations -->
  <jaxws:endpoint
    id='EJB3Endpoint'
    address='http://localhost:8080/ejb3_endpoint_archive_name'  
    implementor='my.package.EJB3EndpointImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerEJB3'/>
    </jaxws:invoker>
  </jaxws:endpoint></beans>

Providing custom CXF configuration to the endpoint deployment is useful in cases when users want to use features that are not part of standard JAX-WS specification but CXF implements them. For example see CXF WS-RM tutorial customization file. We are providing custom CXF endpoint configuration there to turn on WS-RM feature for endpoint.

Note

Note

When user incorporates its own CXF configuration to the endpoint archive he must reference either org.jboss.wsf.stack.cxf.InvokerJSE or org.jboss.wsf.stack.cxf.InvokerEJB3 jaxws invoker bean there for each jaxws endpoint.

 

Here is the CXF documentation about supported WS-* specifications.

 

Apache CXF has a thorough support for WS-Addressing; details are available at the following pages:

CXF WS-Addressing documentation CXF WS-Addressing configuration

 

Given the JAXWS specification currently covers WS-Addressing basic fuctionalities, users simply needing to enable it can make use of the @Addressing annotation and AddressingFeature, as shown in the following JBossWS-CXF tutorial:

JBossWS-CXF WS-Addressing Tutorial

 

Apache CXF leverages WSS4J to provide WS-Security functionalities. This means that thanks to the JBossWS-CXF integration, users can create web service applications using CXF - WSS4J implementation of WS-Security and deploy them on JBoss Application Server.

 

The Apache CXF documentation features an brief chapter on how to use WSS4J security in CXF. Here below instead you'll find some explanations on how to create a simple application and what you need to do to leverage WSS4J security on JBoss.

 

Creating the web service endpoint

First of all you need to create the web service endpoint / client using JAX-WS. This can be achieved in many ways, for instance you might want to:

  1. write your endpoint implementation, then run the wsprovide JBoss commandline tool which generates the service contract (bottom-up approach);

  2. run the wsconsume JBoss commandline tool to get the client artifacts from the service contract (top-down approach);

  3. write your client implementation.

 

Turn on WS-Security

WSS4J security is triggered through interceptors that are added to the service and/or client. These interceptors allows you to perform the most common WS-Security related process:

  • pass authentication tokens between services;

  • encrypt messages or parts of messages;

  • sign messages;

  • timestamp messages.

Interceptors can be added either programmatically or through the Spring xml configuration of endpoints.

For instance, on server side, you can configure signature and encryption in the jboss-cxf.xml file this way:

<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    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'>
  
  <bean id="Sign_Request" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="Timestamp Signature Encrypt"/>
        <entry key="signaturePropFile" value="bob.properties"/>
        <entry key="decryptionPropFile" value="bob.properties"/>
        <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback"/>
      </map>
    </constructor-arg>
  </bean>
  
  <bean id="Sign_Response" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="Timestamp Signature Encrypt"/>
        <entry key="user" value="bob"/>
        <entry key="signaturePropFile" value="bob.properties"/>
        <entry key="encryptionPropFile" value="bob.properties"/>
        <entry key="encryptionUser" value="Alice"/>
        <entry key="signatureKeyIdentifier" value="DirectReference"/>
        <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback"/>
        <entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
        <entry key="encryptionParts" value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
        <entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
      </map>
    </constructor-arg>
  </bean>
  
  <jaxws:endpoint
    id='ServiceImpl'
    address='http://@jboss.bind.address@:8080/jaxws-samples-wsse-sign-encrypt'
    implementor='org.jboss.test.ws.jaxws.samples.wsse.ServiceImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerJSE'/>
    </jaxws:invoker>
    <jaxws:outInterceptors>
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
        <ref bean="Sign_Response"/>
    </jaxws:outInterceptors>
    <jaxws:inInterceptors>
        <ref bean="Sign_Request"/>
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
    </jaxws:inInterceptors>
  </jaxws:endpoint>
</beans>

This specifies the whole security configuration (including algorithms and elements to be signed/encrypted); moreover it references a properties file (bob.properties) providing the keystore-related information:

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=password
org.apache.ws.security.crypto.merlin.keystore.alias=bob
org.apache.ws.security.crypto.merlin.file=bob.jks

As you can see in the jbossws-cxf.xml file above, a keystore password callback handler is also configured; while the properties file has the password for the keystore, this callback handler is used to set password for each key (it has to match the one used when each key was imported in the store). Here's a trivial example:

package org.jboss.test.ws.jaxws.samples.wsse;
 
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
 
public class KeystorePasswordCallback implements CallbackHandler
{
   private Map<String, String> passwords = new HashMap<String, String>();
 
   public KeystorePasswordCallback()
   {
      passwords.put("alice", "password");
      passwords.put("bob", "password");
   }
 
   public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
   {
      for (int i = 0; i < callbacks.length; i++)
      {
         WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
         String pass = passwords.get(pc.getIdentifer());
         if (pass != null)
         {
            pc.setPassword(pass);
            return;
         }
      }
   }
 
   public void setAliasPassword(String alias, String password)
   {
      passwords.put(alias, password);
   }
}

On client side, you can similarly setup the interceptors programmatically; here is an excerpt of the client for the above described endpoint (of course you can also leverage a proper Spring configuration for loading an already configured CXF Bus instance):

Endpoint cxfEndpoint = client.getEndpoint();
Map<String,Object> outProps = new HashMap<String,Object>();
outProps.put("action", "Timestamp Signature Encrypt");
outProps.put("user", "alice");
outProps.put("signaturePropFile", "META-INF/alice.properties");
outProps.put("signatureKeyIdentifier", "DirectReference");
outProps.put("passwordCallbackClass", "org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback");
outProps.put("signatureParts", "{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put("encryptionPropFile", "META-INF/alice.properties");
outProps.put("encryptionUser", "Bob");
outProps.put("encryptionParts", "{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
outProps.put("encryptionKeyTransportAlgorithm", "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); //request
cxfEndpoint.getOutInterceptors().add(wssOut);
cxfEndpoint.getOutInterceptors().add(new SAAJOutInterceptor());
      
Map<String,Object> inProps= new HashMap<String,Object>();
inProps.put("action", "Timestamp Signature Encrypt");
inProps.put("signaturePropFile", "META-INF/alice.properties");
inProps.put("passwordCallbackClass", "org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback");
inProps.put("decryptionPropFile", "META-INF/alice.properties");
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); //response
cxfEndpoint.getInInterceptors().add(wssIn);
cxfEndpoint.getInInterceptors().add(new SAAJInInterceptor());
Package and deploy

To deploy your web service endpoint, you need to package the following files along with your service implementation and wsdl contract:

  • the jbossws-cxf.xml descriptor

  • the properties file

  • the keystore file (if required for signature/encryption)

  • the keystore password callback handler class

For instance, here are the archive contents for the afore mentioned signature & encryption sample (POJO endpoint):

[alessio@localhost cxf-tests]$ jar -tvf target/test-libs/jaxws-samples-wsse-sign-encrypt.war 
   0 Tue Jun 03 19:41:26 CEST 2008 META-INF/
 106 Tue Jun 03 19:41:24 CEST 2008 META-INF/MANIFEST.MF
   0 Tue Jun 03 19:41:26 CEST 2008 WEB-INF/
   0 Tue Jun 03 19:41:26 CEST 2008 WEB-INF/classes/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
1628 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/KeystorePasswordCallback.class
 364 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/ServiceIface.class
 859 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/ServiceImpl.class
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/jaxws/
 685 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/jaxws/SayHello.class
1049 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/jaxws/SayHelloResponse.class
2847 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/jbossws-cxf.xml
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/wsdl/
1575 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/wsdl/SecurityService.wsdl
 641 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/wsdl/SecurityService_schema1.xsd
1820 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/bob.jks
 311 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/bob.properties
 573 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/web.xml

On client side, instead, you only need the properties and keystore files (assuming you setup the interceptors programmatically).

Check that JBossWS-CXF is installed on your current JBoss Application Server, deploy and test your WS-Security-enabled application.

 

 

Starting from JBossWS-CXF 3.1.1, WS-Security Policy implementation is available and can be used to configure WS-Security more easily.

Please refer to the Apache CXF documentation; basically instead of manually configuring interceptors in the client or through jbossws-cxf.xml descriptor, you simply provide the right policies in the WSDL contract.

  ...
  <binding name="SecurityServicePortBinding" type="tns:ServiceIface">
    <wsp:PolicyReference URI="#SecurityServiceSignPolicy"/>
  ...
  <wsp:Policy wsu:Id="SecurityServiceSignPolicy"
    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:AsymmetricBinding xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
                <wsp:Policy>
                    <sp:InitiatorToken>
                        <wsp:Policy>
                            <sp:X509Token sp:IncludeToken='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient'>
                                <wsp:Policy>
                                    <sp:WssX509V3Token10 />
                                </wsp:Policy>
                            </sp:X509Token>
                        </wsp:Policy>
                    </sp:InitiatorToken>
                    <sp:RecipientToken>
                        <wsp:Policy>
                            <sp:X509Token sp:IncludeToken='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always'>
                                <wsp:Policy>
                                    <sp:WssX509V3Token10 />
                                </wsp:Policy>
                            </sp:X509Token>
                        </wsp:Policy>
                    </sp:RecipientToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic256 />
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Strict />
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:OnlySignEntireHeadersAndBody />
                </wsp:Policy>
            </sp:AsymmetricBinding>
            <sp:Wss10 xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
                <wsp:Policy>
                    <sp:MustSupportRefEmbeddedToken />
                </wsp:Policy>
            </sp:Wss10>
            <sp:SignedParts xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
                <sp:Body />
            </sp:SignedParts>
        </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
  ...

Just few properties are also required to be set either in the message context or in the jbossws-cxf.xml descriptor.

((BindingProvider)proxy).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());
((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/alice.properties"));
((BindingProvider)proxy).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/alice.properties"));
<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    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='ServiceImpl'
    address='http://@jboss.bind.address@:8080/jaxws-samples-wssePolicy-sign'
    implementor='org.jboss.test.ws.jaxws.samples.wssePolicy.ServiceImpl'>
    
    <jaxws:properties>
       <entry key="ws-security.signature.properties" value="bob.properties"/>
       <entry key="ws-security.encryption.properties" value="bob.properties"/>
       <entry key="ws-security.callback-handler" value="org.jboss.test.ws.jaxws.samples.wssePolicy.KeystorePasswordCallback"/>
    </jaxws:properties>
  </jaxws:endpoint>
</beans>

 

 

The Username Token Profile can of course be used to provide client's credentials to the target endpoint. Starting from JBossWS-CXF 3.3.0 (which includes Apache CXF 2.2.8), the username token information can be used for authentication and authorization on JBoss AS (JAAS integration).

On server side, you need to specify what follows (for instance using a jbossws-cxf.xml descriptor):

<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xmlns:util='http://www.springframework.org/schema/util'
  xsi:schemaLocation='http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-2.0.xsd
    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'>
  
  <bean id="SecurityContextIn"
     class="org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="UsernameToken"/> 
      </map>
    </constructor-arg>
  </bean>
 
  <util:map id="methodPermissions">
     <entry key="sayHello" value="friend"/> 
     <entry key="greetMe" value="snoopies"/> 
  </util:map>
 
  <bean id="AuthorizeIn"
    class="org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor">
   <property name="methodRolesMap" ref="methodPermissions"/> 
  </bean>
  
  <jaxws:endpoint
    id='ServiceImpl'
    address='http://@jboss.bind.address@:8080/jaxws-samples-wsse-username-authorize'
    implementor='org.jboss.test.ws.jaxws.samples.wsse.ServiceImpl'>
    <jaxws:inInterceptors>
        <ref bean="SecurityContextIn"/>
        <ref bean="AuthorizeIn"/>
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
    </jaxws:inInterceptors>
  </jaxws:endpoint>
</beans>

 

Authentication and authorization will simply be delegated to the security domain configured for the endpoint. Of course you can specify the login module you prefer for that security domain (refer the application server / security documentation for that).

 

On client side, the username is provided through API (or a custom Spring configuration used to load the Bus):

 

Endpoint cxfEndpoint = client.getEndpoint();
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put("action", "UsernameToken");
outProps.put("user", username);
outProps.put("passwordType", "PasswordText");
outProps.put("passwordCallbackClass", "org.jboss.test.ws.jaxws.samples.wsse.UsernamePasswordCallback");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); //request
cxfEndpoint.getOutInterceptors().add(wssOut);
cxfEndpoint.getOutInterceptors().add(new SAAJOutInterceptor());

 

The password instead is provided through a password callback handler that needs to implement javax.security.auth.callback.CallbackHandler, similarly to the keystore's password callback handler.

 

If you're running an older JBossWS-CXF version, or you're not interested in the the application server auth integration, you can use a password callback handler on server side too, configured through a WSS4JInInterceptor:

 

<bean id="UsernameToken_Request">
  <constructor-arg>
    <map>
      <entry key="action" value="UsernameToken"/> 
      <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.ServerUsernamePasswordCallback"/> 
    </map>
  </constructor-arg>
</bean>

 

package org.jboss.test.ws.jaxws.samples.wsse;
 
import java.io.IOException;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
 
public class ServerUsernamePasswordCallback implements CallbackHandler
{
   public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
   {
      WSPasswordCallback pc = (WSPasswordCallback)callbacks[0];
      if (!("kermit".equals(pc.getIdentifier()) && "thefrog".equals(pc.getPassword())))
         throw new SecurityException("User '" + pc.getIdentifier() + "' with password '" + pc.getPassword() + "' not allowed.");
   }
}

Here is a tutorial on how to deploy and invoke a JMS endpoint using JBossWS-CXF.

 

Apache CXF comes with pluggable transport layers, allowing different transport modules to be used.

 

The JBossWS-CXF integration leverages CXF servlet transport for the deployment of endpoints on top of the running JBoss Application Server.

 

However, when users directly leverage the JAXWS Endpoint.publish(String s) API, endpoints are expected to be deployed on a standalone http server started just for serving the specified endpoint. Apache CXF currently defaults to using the Jetty based http transport. Starting from release 3.4.0, the JBossWS-CXF integration instead uses a different http transport module based on the http server embedded in JDK6 distributions. Thanks to Apache CXF transport pluggability, users can still change the transport they want to use in this case by simply replacing the jbossws-cxf-transports-httpserver.jar library with another http transport one, for instance the cxf-rt-transports-http-jetty.jar.

 

In the jbossws-cxf-client.jar[*] file you will find META-INF/cxf/cxf-extension-jbossws.xml, which contains the JBossWS extensions to the Apache CXF stack. In that file you need to enable

  <cxf:bus>
    <cxf:inInterceptors>
      <ref bean="logInbound"/>
    </cxf:inInterceptors>
    <cxf:outInterceptors>
      <ref bean="logOutbound"/>
    </cxf:outInterceptors>
    <cxf:inFaultInterceptors>
      <ref bean="logOutbound"/>
    </cxf:inFaultInterceptors>
  </cxf:bus>

 

Once you've uncommented the cxf-extension-jbossws.xml contents, you need to re-pack the jar/zip.

 

[*] The cxf-extension-jbossws.xml is available from version 3.2.2; if you don't have that file, you can manually add it and link it in cxf.extensions file.

 

Finally, please note that logging can be enabled in many ways with Apache CXF, see the following documentation pages for instance: