JBoss.orgCommunity Documentation
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.
Most of the Apache CXF features are configurable using the org.apache.cxf.Bus class. New Bus instances are produced by the currently configured org.apache.cxf.BusFactory implementation the following way:
Bus bus = BusFactory.newInstance().createBus();
The algorithm for selecting the actual implementation of BusFactory to be used leverages the Service API, basically looking for optional configurations in META-INF/services/... location using the current classloader. JBossWS-CXF integration comes with his own implementation of BusFactory, org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory, that allows for automatic detection of Spring availability as well as seamless setup of JBossWS customizations on top of Apache CXF. JBossWSBusFactory is automatically retrieved by the BusFactory.newInstance() call above.
JBossWS users willing to explicitely use functionalities of org.apache.cxf.bus.spring.SpringBusFactory or org.apache.cxf.bus.CXFBusFactory, get the same API with JBossWS additions through JBossWSBusFactory:
String myConfigFile = ...
Bus bus = new JBossWSBusFactory().createBus(myConfigFile);
Map<Class, Object> myExtensions = new HashMap<Class, Object>(); myExtensions.put(...); Bus bus = new JBossWSBusFactory().createBus(myExtensions);
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
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
The Apache CXF technical documentation on WS-RealiableMessaging is available as a reference at the following pages:
CXF WS-ReliableMessaging documentation CXF WS-ReliableMessaging configuration
For a complete tutorial on how to enable WS-ReliableMessaging in a user client-server application, please take a look at:
JBossWS-CXF WS-ReliableMessaging Tutorial
Apache CXF technical documentation on the WS-Policy engine and its configuration is available at:
CXF WS-Policy documentation CXF WS-Policy configuration
For a complete sample of WS-Policy usage, please take a look at the JBossWS-CXF WS-ReliableMessaging tutorial below, as WS-RM is implemented leveraging policies there:
JBossWS-CXF WS-Policy & WS-ReliableMessaging Tutorial
When building up the Bus without Spring libraries available on the classpath, JBossWSBusFactory still makes sure the PolicyEngine (as well as the RMManager) is properly setup. This allows users to leverage basic WS-Policy functionalities the same way they'd do with a full Spring-enabled Bus.
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.
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:
write your endpoint implementation, then run the wsprovide JBoss commandline tool which generates the service contract (bottom-up approach);
run the wsconsume JBoss commandline tool to get the client artifacts from the service contract (top-down approach);
write your client implementation.
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());
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):
an interceptor for performing authentication and populating a valid SecurityContext; the provided interceptor should extend org.apache.cxf.ws.security.wss4j.AbstractUsernameTokenAuthenticatingInterceptor, in particular JBossWS integration comes with org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor for this;
an interceptor for performing authorization; CXF requires that to extend org.apache.cxf.interceptor.security.AbstractAuthorizingInInterceptor, for instance the SimpleAuthorizingInterceptor can be used for simply mapping endpoint operations to allowed roles.
<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."); } }
The JBossWS-CXF source distribution comes with some samples using X.509 certificate signature and encryption as well as Username Token Profile. You can find them in package org.jboss.test.ws.jaxws.samples.wsse .
When requiring encryption, you might need to install an additional JCE provider supporting the crypto algorithms Apache CXF uses. This usually means the Bouncy Castle provider need to be configured in your JRE. Please refer the Native stack user guide for further information about this.
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: