Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WS-Security UsernameToken with Apache CXF

Tags:

java

soap

cxf

I have a java application that interacts with a SOAP service. I used the WSDL to generate a java client via CXF, but I need to authenticate my calls using ws-security. I am looking for a code-only way to do this, and I don't have any xml configurations. This is what I have tried:

Map ctx = ((BindingProvider)port).getRequestContext();
ctx.put("ws-security.username", "joe");
ctx.put("ws-security.password", "joespassword");
port.makeSoapCall();

But I get a parse error for invalid WS-Security header. What is the right way to do this?

In SOAP UI, I can do this easily by right-clicking the soap header, clicking "Add WSS UsernameToken", and selecting "Password Text"

like image 245
user1007895 Avatar asked Oct 28 '14 02:10

user1007895


People also ask

What does Apache CXF use for integration with WSS4J and security?

CXF relies on WSS4J in large part to implement WS-Security. Within your own services, WS-Security can be activated by using WS-SecurityPolicy, which provides a comprehensive and sophisticated validation of the security properties of a received message.

What is Apache CXF used for?

Apache CXF™ is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.

What is Camel CXF?

In Apache Camel, the Camel CXF component is the key to integrating routes with Web services. You can use the Camel CXF component to create a CXF endpoint, which can be used in either of the following ways: Consumer — (at the start of a route) represents a Web service instance, which integrates with the route.

What is SOAP WS-Security?

Web Services Security (WS-Security) describes enhancements to SOAP messaging to provide quality of protection through message integrity, message confidentiality, and single message authentication. WS-Security mechanisms can be used to accommodate a wide variety of security models and encryption technologies.


1 Answers

You are using WS-SecurityPolicy as per the code you shared. How about using WS-Security only and sending across the usernametoken using WSS4JOutInterceptor?

Check the section "Adding the interceptors via the API" in apache cfx ws-security guide here : http://cxf.apache.org/docs/ws-security.html

This is what needs to be done as per the above apache cxf documenation above. You might only need the out interceptor path.

On the client side, you can obtain a reference to the CXF endpoint using the ClientProxy helper:

import org.apache.cxf.frontend.ClientProxy;
...

GreeterService gs = new GreeterService();
Greeter greeter = gs.getGreeterPort();
...
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(greeter);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();

Now you're ready to add the interceptors:

import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
...

Map<String,Object> inProps = new HashMap<String,Object>();
... // how to configure the properties is outlined below;

WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
cxfEndpoint.getInInterceptors().add(wssIn);

Map<String,Object> outProps = new HashMap<String,Object>();
outProps.put("action", "UsernameToken Timestamp");
outProps.put("passwordType", "PasswordDigest"); //remove this line if want to use plain text password
outProps.put("user", "abcd");
outProps.put("passwordCallbackClass", "demo.wssec.client.UTPasswordCallback");

WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);

You will need to write password callback class (UTPasswordCallback) in the example above.

Apache cxf has a complete sample for UserName token here: http://svn.apache.org/repos/asf/cxf/trunk/distribution/src/main/release/samples/ws_security/ut/

From the above link browse to client folder (src/main/java/demo/wssec/client) for user name token and UTPasswordCallback code.

EDIT: If your wsdl expects password as plain text then just remove this line from the code: outProps.put("passwordType", "PasswordDigest");

like image 168
Sonali Avatar answered Oct 05 '22 14:10

Sonali