Adding WS-Security over soap using Apache Camel

WS-Security (Web Services Security) is a protocol which allows you to secure your soap web services. The client, who makes the soap request, has to provide a login and a password in the soap header.

The server receives the soap request, checks the credentials and validates or not the request. With Apache Camel, it is easy to work with soap web services (especially if you use Apache CXF), but handling with WS-Security can be tricky.

The idea is to create an xml template with all required information (including login and password) and add the template to the soap header.
 

public void addSoapHeader(Exchange exchange,String soapHeader){

        List<SoapHeader> soapHeaders = CastUtils.cast((List<?>) exchange.getIn().getHeader(Header.HEADER_LIST));
        SoapHeader newHeader;

        if(soapHeaders == null){

            soapHeaders = new ArrayList<SoapHeader>();
        }
        
        try {
            newHeader = new SoapHeader(new QName("soapHeader"), DOMUtils.readXml(new StringReader(soapHeader)).getDocumentElement());
            newHeader.setDirection(Direction.DIRECTION_OUT);

            soapHeaders.add(newHeader);

            exchange.getIn().setHeader(Header.HEADER_LIST, soapHeaders);

        } catch (Exception e) {
            //log error
        }
    }

Apache Camel uses an Exchange interface which has methods to retrieve or update headers. The soapHeader parameter is a string containing the xml template.

We retrieve the current headers and we add a new header named soapHeader. We convert the soapHeader property from string to XML thanks to the DOMUtils class.

The newHeader.setDirection(Direction.DIRECTION_OUT) instruction means that the header will be applied to a request either leaving a consumer endpoint or entering a producer endpoint (that is, it applies to a WS request message propagating through a route).

Now let’s create the xml template and call the addSoapHeader method:

public void addWSSESecurityHeader(Exchange exchange,String login,String password){

        String soapHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"+ 
        "xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken wsu:Id=\"UsernameToken-50\"><wsse:Username>"
                + login
                + "</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">"
                + password + "</wsse:Password></wsse:UsernameToken></wsse:Security>";

        //Add wsse security header to the exchange

        addSoapHeader(exchange, soapHeader);

    }

As we can see, we need two namespaces in our xml (to handle with WS-Security):

We can then use interesting tags into our xml:

  • wsse :UsernameToken : Includes both username and password information
  • wsse :Username : Username required for authentication
  • wsse :Password : Password required for authentication

Next we just have to call our method addSoapHeaderto add our xml into the soap header. Here’s the full code with a complete Apache Camel route:

package com.example.test;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.camel.Exchange;
import org.apache.camel.util.CastUtils;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.headers.Header;
import org.apache.cxf.headers.Header.Direction;
import org.apache.cxf.helpers.DOMUtils;

public class MyRoute extends RouteBuilder {

    public void addSoapHeader(Exchange exchange,String soapHeader){

        List<SoapHeader> soapHeaders = CastUtils.cast((List<?>) exchange.getIn().getHeader(Header.HEADER_LIST));
        SoapHeader newHeader;

        if(soapHeaders == null){

            soapHeaders = new ArrayList<SoapHeader>();
        }
        
        try {
            newHeader = new SoapHeader(new QName("soapHeader"), DOMUtils.readXml(new StringReader(soapHeader)).getDocumentElement());
            newHeader.setDirection(Direction.DIRECTION_OUT);

            soapHeaders.add(newHeader);

            exchange.getIn().setHeader(Header.HEADER_LIST, soapHeaders);

        } catch (Exception e) {
            //log error
        }
    }

    public void addWSSESecurityHeader(Exchange exchange,String login,String password){

        String soapHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"+ 
        "xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken wsu:Id=\"UsernameToken-50\"><wsse:Username>"
                + login
                + "</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">"
                + password + "</wsse:Password></wsse:UsernameToken></wsse:Security>";

        //Add wsse security header to the exchange

        addSoapHeader(exchange, soapHeader);

    }

    @Override
    public void configure() throws Exception {
        from("endpointIn")
        .process(new Processor(){
            @Override
            public void process(Exchange exchange) throws Exception {
                addWSSESecurityHeader(exchange, "login","password");
            }
        })
        .to("endointOut") ;
    }
}
Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


− 6 = one



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books