Last active
February 4, 2021 12:08
-
-
Save hugithordarson/0efa7e7fb76afdd8372e7f9636105c7b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- 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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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