/*
* JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
* LLC, and individual contributors by the @authors tag. See the copyright.txt
* in the distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.jboss.soa.esb.services.security.auth.ws;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.dom.DOMSource;
import org.jboss.internal.soa.esb.util.StreamUtils;
import org.jboss.soa.esb.util.ClassUtil;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/**
* This class contains methods for creating SOAPMessages with
* different headers, for example Security headers.
*
* @author <a href="mailto:dbevenius@redhat.com">Daniel Bevenius</a>
*
*/
public class WSTestUtil
{
private WSTestUtil() { }
/**
* Creates a SOAPMessage with a BinarySecurityToken header.
* </p>
* <pre>{@code
* <soap:Header>
* <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
* <wsse:BinarySecurityToken EncodingType="encodingType" ValueType="valueTyep">cert
* </wsse:Security>
* }</pre>
* <br><br>
* Example usage:
* <pre>{@code
* SOAPMessage soap = WSTestUtil.createWithBinarySecurityToken("Base64Binary", "X509v3", WSTestUtil.getStringFromFile("cert-example.xml", getClass()));
* }</pre>
*
* @param encodingType - The encoding type( Base64Binary, HexBinary)
* @param valueType - the type of key ( they key is the value of the BinarySecurityToken element )
* @param cert - the cert represented as a string
* @return SOAPMessage - populated with the BinarySecurityToken security header
* @throws SOAPException - if something goes wrong.
*/
public static SOAPMessage createWithBinarySecurityToken(final String encodingType, final String valueType, final String cert) throws SOAPException
{
SOAPMessage soapMessage = createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPHeader soapHeader = soapEnvelope.getHeader();
Name security = soapEnvelope.createName(SoapConstants.WSSE_LN, "wsse", SoapConstants.WSSE_NS);
SOAPHeaderElement headerElement = soapHeader.addHeaderElement( security );
createBinaryHeaderElement(soapEnvelope, headerElement, encodingType, valueType, cert );
return soapMessage;
}
/**
* Creates a SOAPMessage with a UsernameToken header.
* <p/>
* <br>
* <pre>{@code
* <soap:Header>
* <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
* <wsse:UsernameToken>
* <wsse:Username>Clark</wsse:Username>
* <wsse:Password>griswald</wsse:Password>
* </wsse:UsernameToken>
* </wsse:Security>
* </soap:Header>
*
* }</pre>
* <br><br>
* Example usage:
* <pre>{@code
* SOAPMessage soap = WSTestUtil.createWithUsernameToken(username, password);
* }</pre>
*
* @param username
* @param password
* @return SOAPMessage - populated with the UsernameToken security header
* @throws SOAPException - if something goes wrong.
*/
public static SOAPMessage createWithUsernameToken(final String username, final String password) throws SOAPException
{
SOAPMessage soapMessage = createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPHeader soapHeader = soapEnvelope.getHeader();
Name security = soapEnvelope.createName(SoapConstants.WSSE_LN, "wsse", SoapConstants.WSSE_NS);
SOAPHeaderElement headerElement = soapHeader.addHeaderElement( security );
createUsernameTokenHeaderElement(soapEnvelope, headerElement, username, password );
return soapMessage;
}
public static SOAPMessage createMessage() throws SOAPException
{
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
return soapMessage;
}
public static String getStringFromFile(final String fileName, final Class<?> clazz )
{
InputStream inputStream = ClassUtil.getResourceAsStream(fileName, clazz );
return new String(StreamUtils.readStream(inputStream));
}
public static void dumpSoap(final SOAPMessage soap )
{
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
try
{
soap.writeTo(bout);
System.out.println(new String(bout.toByteArray()));
}
catch (final SOAPException e1)
{
e1.printStackTrace();
}
catch (final IOException e1)
{
e1.printStackTrace();
}
}
/**
* Creates a SOAPMessage from the contents of the passed in filename.
*
* @param fileName - the file containing the soap envelope.
* @param clazz - the class used to search from ( think getClass().getResource...).
* @return SOAPMessage - a SOAPMessage populated from the contents of the file.
*
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
* @throws SOAPException
*/
public static SOAPMessage createMessage( final String fileName, final Class<?> clazz ) throws ParserConfigurationException, SAXException, IOException, SOAPException
{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder builder = dbFactory.newDocumentBuilder();
Document document = builder.parse( ClassUtil.getResource(fileName, clazz).getFile());
DOMSource domSource = new DOMSource(document);
SOAPMessage message = createMessage();
SOAPPart soapPart = message.getSOAPPart();
soapPart.setContent(domSource);
return message;
}
public static SOAPMessage createMessage( final String fileName ) throws ParserConfigurationException, SAXException, IOException, SOAPException
{
return createMessage(fileName, WSTestUtil.class );
}
private static SOAPElement createBinaryHeaderElement(
final SOAPEnvelope soapEnvelope,
final SOAPHeaderElement headerElement,
final String encodingType,
final String valueType,
final String cert) throws SOAPException
{
// create the BinarySecurityToken element
Name binarySecurityTokenName = soapEnvelope.createName("BinarySecurityToken", "wsse", SoapConstants.WSSE_NS);
SOAPElement binarySecurityTokenElement = headerElement.addChildElement(binarySecurityTokenName);
// add the EncodingType attribute
binarySecurityTokenElement.addAttribute(soapEnvelope.createName("EncodingType"), encodingType);
// add the ValueType attribute
binarySecurityTokenElement.addAttribute(soapEnvelope.createName("ValueType"), valueType);
// add the certificate as a text node
binarySecurityTokenElement.addTextNode(cert);
return binarySecurityTokenElement;
}
private static SOAPElement createUsernameTokenHeaderElement(
final SOAPEnvelope soapEnvelope,
final SOAPHeaderElement headerElement,
final String username,
final String password) throws SOAPException
{
// create the UsernameToken element
Name usernameTokenName = soapEnvelope.createName("UsernameToken", "wsse", SoapConstants.WSSE_NS);
SOAPElement usernameTokenElement = headerElement.addChildElement(usernameTokenName);
// create and add the Username sub element
if ( username != null )
{
Name usernameName = soapEnvelope.createName("Username", "wsse", SoapConstants.WSSE_NS);
SOAPElement usernameNode = usernameTokenElement.addChildElement(usernameName);
usernameNode.addTextNode(username);
}
// create and add the password sub element
if ( password != null )
{
Name passwordName = soapEnvelope.createName("password", "wsse", SoapConstants.WSSE_NS);
SOAPElement passwordNode = usernameTokenElement.addChildElement(passwordName);
passwordNode.addTextNode(password);
}
return usernameTokenElement;
}
}