Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<!-- keyrt með mvn jaxws:wsimport -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.6</version>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlUrls>
<wsdlUrl>https://ws.b2b.is/Statements/20130201/BillService.svc?wsdl</wsdlUrl>
</wsdlUrls>
<sourceDestDir>${project.build.sourceDirectory}</sourceDestDir>
<packageName>nb.arion.services.bill</packageName>
<args>
<arg>-B-XautoNameResolution</arg>
<arg>-extension</arg>
</args>
<vmArgs>
<arg>-Djavax.xml.accessExternalSchema=all</arg>
</vmArgs>
<verbose>true</verbose>
</configuration>
</plugin>
package nb;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.components.crypto.Merlin;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.message.WSSecTimestamp;
import org.apache.ws.security.message.WSSecUsernameToken;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class WSSecurityHeaderWSS4J implements SOAPHandler<SOAPMessageContext> {
private static Merlin _crypto;
private String _username;
private String _password;
public WSSecurityHeaderWSS4J( String username, String password ) {
_username = username;
_password = password;
}
@Override
public boolean handleMessage( SOAPMessageContext messageContext ) {
Boolean outboundProperty = (Boolean)messageContext.get( MessageContext.MESSAGE_OUTBOUND_PROPERTY );
if( outboundProperty.booleanValue() ) {
try {
SOAPMessage message = messageContext.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
messageContext.getMessage().writeTo( out );
String beforeString = new String( out.toByteArray() );
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware( true );
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inStream = new InputSource();
inStream.setCharacterStream( new StringReader( beforeString ) );
Document document = builder.parse( inStream );
secure( document );
String afterString = toString( document );
StreamSource source = new StreamSource( new ByteArrayInputStream( afterString.getBytes( "utf-8" ) ) );
message.getSOAPPart().setContent( source );
}
catch( SOAPException | IOException | ParserConfigurationException | SAXException e ) {
throw new RuntimeException( e );
}
}
return true;
}
private void secure( Document document ) {
try {
WSSecHeader secHeader = new WSSecHeader();
secHeader.setMustUnderstand( true );
secHeader.insertSecurityHeader( document );
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setTimeToLive( 300 );
timestamp.build( document, secHeader );
WSSecUsernameToken token = new WSSecUsernameToken();
token.setUserInfo( _username, _password );
token.setPasswordType( WSConstants.PASSWORD_TEXT );
token.addNonce();
token.addCreated();
token.build( document, secHeader );
WSSConfig config = new WSSConfig();
config.setWsiBSPCompliant( false );
WSSecSignature builder = new WSSecSignature( config );
builder.setUserInfo( "<key-name>", "<pass>" );
builder.setUseSingleCertificate( true );
builder.setKeyIdentifierType( WSConstants.BST_DIRECT_REFERENCE );
WSEncryptionPart bodyPart = new WSEncryptionPart( WSConstants.ELEM_BODY, WSConstants.URI_SOAP12_ENV, "" );
builder.setParts( Arrays.asList( bodyPart ) );
builder.build( document, crypto(), secHeader );
}
catch( Exception e ) {
throw new RuntimeException( e );
}
}
private static Merlin crypto() {
if( _crypto == null ) {
try {
Properties p = new Properties();
p.put( "org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin" );
p.put( "org.apache.ws.security.crypto.merlin.file", "/some-keystore.jks" );
p.put( "org.apache.ws.security.crypto.merlin.keystore.password", "<pass>" );
p.put( "org.apache.ws.security.crypto.merlin.keystore.type", "jks" );
_crypto = (Merlin)CryptoFactory.getInstance( p, WSSecurityHeaderWSS4J.class.getClassLoader() );
}
catch( WSSecurityException e ) {
throw new RuntimeException( e );
}
}
return _crypto;
}
private static String toString( Document doc ) {
try {
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" );
transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
transformer.transform( new DOMSource( doc ), new StreamResult( sw ) );
return sw.toString();
}
catch( Exception ex ) {
throw new RuntimeException( "Error converting to String", ex );
}
}
@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security" );
HashSet<QName> headers = new HashSet<>();
headers.add( securityHeader );
return headers;
}
@Override
public boolean handleFault( SOAPMessageContext context ) {
return false;
}
@Override
public void close( MessageContext context ) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment