machacapopa has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I've been searching all over the place for some examples on how to generate a digitally signed SOAP request header. I've added an example of what my generated request should look like. Any help, pointers, or link to examples would be greatly appreciated.

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envel +ope/" xmlns:v1="some name space"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004 +/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://doc +s.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0. +xsd"> <wsse:BinarySecurityToken EncodingType="http://docs.oasis- +open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base6 +4Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-2004 +01-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-38899A2DEAAE0A0A63 +1438825555">MIIFazCCBFOgAwIBAgITBnGseFYWOGKEGKVHi/3Ww90xvzANBgkqhkiG9 +w0BAQsFADCBtTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQHEw +dDaGljYWdvMSEwHwYDVQQKExhUcn</wsse:BinarySecurityToken> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig# +" Id="SIG-38899A2DEA412885"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w +3.org/2001/10/xml-exc-c14n#"> <ec:InclusiveNamespaces xmlns:ec="http://www.w +3.org/2001/10/xml-exc-c14n#" PrefixList="soapenv v1"/> </ds:CanonicalizationMethod> <ds:SignatureMethod Algorithm="http://www.w3.org/2 +000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#id-38899A2DEAAE0A0A654653"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org +/2001/10/xml-exc-c14n#"> <ec:InclusiveNamespaces xmlns:ec="http +://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="v1"/> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/ +2000/09/xmldsig#sha1"/> <ds:DigestValue>eGnt5SFabhhjgkjhg24</ds:Digest +Value> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>E81kRkC92PFjxn5rr6UB8Ul1BOiaSLRNySs +2qfAZxScXgjxjhgY7xmSCcxAs</ds:SignatureValue> <ds:KeyInfo Id="KI-38899A2DEAAE0A0A631316532131535"> <wsse:SecurityTokenReference wsu:Id="STR-38899A2DE +AAE0A0A63313156165"> <wsse:Reference URI="#X509-38899A2DEAAE0A06541 +651515" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-20040 +1-wss-x509-token-profile-1.0#X509v3"/> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oa +sis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-38899A2DEAAE0A0 +A631438865165165165"> <v1:Request> <v1:transactionId>SCSP00000054412256</v1:transactionId> <v1:deviceid>001234567452</v1:deviceid> <v1:cSRComments>blah</v1:cSRComments> <v1:suppressProvisioning>blah</v1:suppressProvisioning> <v1:reasonCode>blah</v1:reasonCode> <v1:source>OEM</v1:source> <v1:overrideURL/> </v1:Request> </soapenv:Body> </soapenv:Envelope>

Replies are listed 'Best First'.
Re: Generate a signed SOAP request
by tangent (Parson) on Aug 31, 2015 at 21:59 UTC
    Here is a nice and laborious way to do it using SOAP::Lite - I copied the methods from this node from 2006. You need to work backwards up the tree calling the name/attr/value sequence on each node, and then combining them at the various levels. Have fun :)
    use SOAP::Lite; SOAP::Lite->import(+trace => 'all'); my $uri = 'urn:Foo'; my $proxy = 'http://localhost/'; my $client = SOAP::Lite ->readable(1) ->uri($uri) ->proxy($proxy); $client->autotype(0); my $security_token = 'MIIFazCCBFOgAwIBAg'; my $signature_value = 'E81kRkC92PFjxn5rr6'; my $BinarySecurityToken = SOAP::Header->name('wsse:BinarySecurityToken +') ->attr({ 'EncodingType' => 'http://docs.oasis-open.org/etc', 'ValueType' => 'http://docs.oasis-open.org/etc', 'wsu:Id' => 'X509-38899A2DEAAE0A0A' }) ->value($security_token); my $CanonicalizationMethod = SOAP::Header->name('ds:CanonicalizationMe +thod') ->value('Cmethod'); my $SignatureMethod = SOAP::Header->name('ds:SignatureMethod') ->value('SignatureMethod'); my $SignedInfo = SOAP::Header->name('ds:SignedInfo') ->value(\SOAP::Header->value($CanonicalizationMethod, $SignatureMe +thod)); my $Signature = SOAP::Header->name('ds:Signature') ->value(\$SignedInfo); my $SignatureValue = SOAP::Header->name('ds:SignatureValue') ->value($signature_value); my $security = SOAP::Header->name('wsse:Security') ->attr({ 'xmlns:wsse' => 'http://docs.oasis-open.org/etc', 'xmlns:wsu' => 'http://docs.oasis-open.org/etc' }) ->value(\SOAP::Header->value($BinarySecurityToken,$Signature,$Sign +atureValue) ); my $elem1 = SOAP::Data->name('ELEM1' => "value1"); my $elem2 = SOAP::Data->name('ELEM2' => "value2"); my $response = $client->mymethod( $security, $elem1, $elem2 );
     
    Which gives me this output:
     
    <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/etc" xmlns:w +su="http://docs.oasis-open.org/etc"> <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.o +rg/etc" ValueType="http://docs.oasis-open.org/etc" wsu:Id="X509-38899 +A2DEAAE0A0A">MIIFazCCBFOgAwIBAg</wsse:BinarySecurityToken> <ds:Signature> <ds:SignedInfo> <ds:CanonicalizationMethod>Cmethod</ds:CanonicalizationMetho +d> <ds:SignatureMethod>SignatureMethod</ds:SignatureMethod> </ds:SignedInfo> </ds:Signature> <ds:SignatureValue>E81kRkC92PFjxn5rr6</ds:SignatureValue> </wsse:Security> </soap:Header> <soap:Body> <mymethod xmlns="urn:Foo"> <ELEM1>value1</ELEM1> <ELEM2>value2</ELEM2> </mymethod> </soap:Body> </soap:Envelope>
Re: Generate a signed SOAP request
by Anonymous Monk on Sep 01, 2015 at 03:20 UTC