File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Web Services and the fly likes Configuring the SOAP Header in client Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Web Services
Bookmark "Configuring the SOAP Header in client" Watch "Configuring the SOAP Header in client" New topic
Author

Configuring the SOAP Header in client

John Farrel
Ranch Hand

Joined: May 24, 2010
Posts: 83
Hi,

I am attempting to write a web service client where the server requires the message to be signed.

An example SOAP header is like so:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urnCNZ.MSP.Wireline.Wholesale.Messages">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="CertId-AE7AC64C0DBF2B1E39128891133619510"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
MIIEKTCCAxGgAwIBAgIKWI4oFAAAAAAB5jANBgkqhkiG9w0BAQUFADBIMUYwRAYDVQQDEz1BZHZhbmNlZCBUZWNobm9sb2d5IFBhcnRuZXJzIExpbWl0ZWQgU3luQ2VydCBTdWIgQ0EgVmVyc2lvbiAyMB4XDTEwMD
YxMzIzMjM0NVoXDTExMDExMzIzMzM0NVowgbMxCzAJBgNVBAYTAk5aMRMwEQYDVQQIEwpXZWxsaW5ndG9uMRMwEQYDVQQHEwpXZWxsaW5ndG9uMREwDwYDVQQKEwhXaXJlbGluZTEMMAoGA1UECxMDT09UMS8
wLQYDVQQDEyZCMkIgVGVzdCAtIFRvdGFsIENvbnN1bWVyIFNlcnZpY2VzIEx0ZDEoMCYGCSqGSIb3DQEJARYZdW5hdHRlbmRlZEB3aXJlbGluZS5jby5uejCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAviEMgAB9dc
luCE+mVv26U/qg7GqD3qxW7lt+5+jB8XuhfXNfVh3CwTVBADO2y9GMFOKyO6WrDD3pdxWu5+tnFDWHUwXj2m22t5iGzzHmBO8ThKcxTuTBN8fC0dnhU8s+XwvT0vzZBxTbhkl19bt71qFEHgQ1RnHMn46MLjClqYkCAwE
AAaOCASswggEnMEQGCSqGSIb3DQEJDwQ3MDUwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3DQMEAgIAgDAHBgUrDgMCBzAKBggqhkiG9w0DBzAdBgNVHQ4EFgQUbO0MRDxmCIDEHz8W+/RDEp37dG0wEwYDVR0lB
AwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgTwMB8GA1UdIwQYMBaAFGAfcIb4a5sQE9kPBr9zkxhmEk68MDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly93d3cuYXRwLmNvLm56L0NEUC9BVFBTWU5DQVYyLmNybDBD
BggrBgEFBQcBAQQ3MDUwMwYIKwYBBQUHMAKGJ2h0dHA6Ly93d3cuYXRwLmNvLm56L2NybC9BVFBTWU5DQVYyLmNydDANBgkqhkiG9w0BAQUFAAOCAQEApSddCrAqDTSrbuMDy8aJTyqpSFyoMxnBU8iEupsCGUeyH
E8FKG1IT1YvsHVS1tgVNDqD5ATpMk1Siu9R5cFZNTK5NcbSdy9yVxfsHedrO4n+T9M7RBMDf95E1rnfRNL36Etpn969TDsQ0BjP2klpG8vKOK/uat3RpCFi/cvD8OEdjQR7hgDTdVp4hlzbjbOLA3/k4IznFXEYjBaa0REsR0iKnZpX
hNu6lDqoZt5JcE4b3ZhUuuin0SIGrRviM9tQgms1dO4LoDsCKgBWXQnlISE7twsh+rAljT0s74uPX9CwUMrkoQGGofTv4USJ4+kx+WqiNQvUCbJMQ0XYRkzdPg==
</wsse:BinarySecurityToken>
<ds:Signature Id="Signature-7" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-8">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<dsigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<dsigestValue>EVhaAzwmZ9Ag1rMNZIuHuepgUpw=</dsigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
mKGPMpYk2Jc+g7aFFpw+nVBT2I3sfF3N8wMNii9bpFLYozc21EzjZpOl6KvaFZhfUa7UyfUrM5Pv
jedQs4fnIHvahMlC6RI/Jui9t9PwHsJXplYDi+OUy1WBvBGGchLXj/Db6Hs7lpd6bduz5W3xkGrG
nnqb+yeNyd0W1Rqc1lc=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-AE7AC64C0DBF2B1E39128891133619511">
<wsse:SecurityTokenReference wsu:Id="STRId-AE7AC64C0DBF2B1E39128891133619512"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Reference URI="#CertId-AE7AC64C0DBF2B1E39128891133619510"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>



I am forced to use jax-rpc, generating code with WSDL2LJAVA.

The calling code is like so:


InformationPort_ServiceLocator loc = new InformationPort_ServiceLocator();
InformationInterface port = loc.getInformationPort();
return port.addressVerification(new AddressVerificationRequest(new AddressVerificationInformation(null, number, subDescription, street, streetType, null, suburb, null, null, null, null, null)));


The question is, when I go to call the web service, how do I load the Header as above? I can certainly construct the XML from SOAPElements, but I've no idea how to generate the data required to be embedded in them.
S. Verma
Greenhorn

Joined: Dec 14, 2010
Posts: 1
Hi John,

From your sample soap message, it looks like your service expects x509 security. In case you are using J2ee based client (client implementation in WAR or EAR file) this security could be configure using deployment descriptor. It requires a number of settings to be done in deployment descriptor along with the certificate.

I do not remember the detailed steps but the point I am making here is, you do not make that kind of soap message using SOAPElement or so. Direct yourself to find the right configurations to be done for the same.

Best of luck!
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41630
    
  55
If it was hand-crafted XML you're sending, or if you were using SAAJ, then you could use the WSS4J directly (although I wouldn't recommend it), but I don't think that's an option with JAX-RPC.

Check the documentation of whichever SOAP stack you're using for how it integrates with WS-Security; all the major ones do.


Ping & DNS - my free Android networking tools app
John Farrel
Ranch Hand

Joined: May 24, 2010
Posts: 83
Thanks for the tips.

After much faffing about I have a client_deploy.xml file like so:



my crypto.properties file looks like this:

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.file=Test.pfx
org.apache.ws.security.crypto.merlin.keystore.type=pkcs12
org.apache.ws.security.crypto.merlin.keystore.password=#B2B Test#
org.apache.ws.security.crypto.merlin.keystore.alias=b2b_test
org.apache.ws.security.crypto.merlin.alias.password=#B2B Test#


However, when I run the web service request, I get a NullPointerException.
I fiddled the client-deploy to just add a username/password and it works fine for that.

Perhaps not finding the crypto file?

Stack trace is:

org.apache.ws.security.components.crypto.CryptoFactory.getProperties(CryptoFactory.java:259)
org.apache.ws.security.components.crypto.CryptoFactory.getInstance(CryptoFactory.java:173)
org.apache.ws.security.handler.WSHandler.loadSignatureCrypto(WSHandler.java:437)
org.apache.ws.security.handler.WSHandler.doSenderAction(WSHandler.java:141)
org.apache.ws.axis.security.WSDoAllSender.invoke(WSDoAllSender.java:170)
org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
org.apache.axis.client.AxisClient.invoke(AxisClient.java:127)
org.apache.axis.client.Call.invokeEngine(Call.java:2784)
org.apache.axis.client.Call.invoke(Call.java:2767)
org.apache.axis.client.Call.invoke(Call.java:2443)
org.apache.axis.client.Call.invoke(Call.java:2366)
org.apache.axis.client.Call.invoke(Call.java:1812)
com.utilibill.telecomNZ.InformationStub.addressVerification(InformationStub.java:916)
com.utilibill.TelecomNZInterface.TelecomNZInterface.getInformation(TelecomNZInterface.java:137)
com.utilibill.frontend.voice.SrvVoiceAddressCheck.processRequest(SrvVoiceAddressCheck.java:135)
com.utilibill.frontend.security.LockedDownServlet.doPost(LockedDownServlet.java:202)
com.utilibill.frontend.security.LockedDownServlet.doGet(LockedDownServlet.java:176)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
java.lang.Thread.run(Thread.java:619)





John Farrel
Ranch Hand

Joined: May 24, 2010
Posts: 83

Problem definitely seems to be that the crypto.properties file can't be found as a resource.
Where should this file live so it's picked up as a resource?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41630
    
  55
Try using an absolute path.
John Farrel
Ranch Hand

Joined: May 24, 2010
Posts: 83

So... success.

To get this to work, I had to:

. include wss4j library

. Call the web service with an EngineConfiguration pointing to my wsdd:

InformationPort_ServiceLocator loc = new InformationPort_ServiceLocator(new FileProvider(ConfigParameter.TELECOMNZ_SIG_WSDD.getPropertyValue()));
InformationInterface port = loc.getInformationPort();

return port.addressVerification(new AddressVerificationRequest(new AddressVerificationInformation(null, number, subDescription, street, streetType, null, suburb, null, null, null, null, null)));


. Write a wsdd like so:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<transport name="http" pivot="javarg.apache.axis.transport.http.HTTPSender"/>
<globalConfiguration >
<requestFlow >
<handler type="javarg.apache.ws.axis.security.WSDoAllSender" >
<parameter name="action" value="Signature"/>
<parameter name="user" value="3e5ae348d06c10fb49752e2a7b04a013_035063ae-06eb-4e69-a102-147b223b70be"/>
<parameter name="passwordCallbackClass" value="com.utilibill.TelecomNZInterface.TelecomNZCallback"/>
<parameter name="passwordType" value="PasswordText"/>
<parameter name="signaturePropFile" value="TelecomNZCrypto.properties"/>
<parameter name="signatureKeyIdentifier" value="DirectReference"/>
</handler>
</requestFlow >
</globalConfiguration >
</deployment>


. Write a password callback class (TelecomNZCallback)

public class TelecomNZCallback implements CallbackHandler
{

/**

* @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])

*/
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException
{

for (Callback callback : callbacks)
{
if (callback instanceof WSPasswordCallback)
{
WSPasswordCallback pc = (WSPasswordCallback) callback;

// set the password given a username

if (pc.getUsage() == WSPasswordCallback.SIGNATURE)
{
pc.setPassword(ConfigParameter.TELECOMNZ_PASSWORD.getPropertyValue());
} else
{
throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
}
}
}
}

}

. Write a crypto.properties file

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.file=TelecomNZSignature.jks
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.alias=3e5ae398d06c10eb49452e2a7b04a013_035863ae-06eb-4f69-a102-147b220b70be
org.apache.ws.security.crypto.merlin.keystore.password=#B2B#
org.apache.ws.security.crypto.merlin.alias.password=#B2B#

. ensure the crypto.properties file and the key store containing the certificate are on the class path of the app.

All in all, a god-awful pain to do. I can't believe this whole area is so difficult, clunky and badly documented.

I'm currently trying to remove the wsdd from this by setting property values directly on the port, but no luck.




 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Configuring the SOAP Header in client