WCF client uses JAVA web service - should I use WCF or just create my own factory parser / message?

We have a business partner who requires us to create a service request message with SAML 2.0 approval. The partner provided two certificates and a test harness for his JAVA web service.

I created a WCF client with CustomBinding to try to recreate the request and use this service, but I'm so frustrated by the nuances of WCF (and the lack of internal support for SAML 2.0). I wonder if I’d better use something like WebClient or HttpWebRequest and encrypt / build and sign the XML web request and do the same for the response. I know that this is a lot of work, but at least I would have been in full control.

Your advice will be greatly appreciated, what I work is displayed below

Note. I was provided with SoapUI test harness for Java service

The provider provided me this request (launched via SOAPUI and retrieved via Fiddler)

 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <SOAP-ENV:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <xenc:EncryptedKey Id="EncKeyId-29B98C291D1FDFB39113352984774895"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference> <ds:X509Data> <ds:X509IssuerSerial> <ds:X509IssuerName>CN=test_server</ds:X509IssuerName> <ds:X509SerialNumber>12356789</ds:X509SerialNumber> </ds:X509IssuerSerial> </ds:X509Data> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue> <!--Omitted --> </xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-3"/> </xenc:ReferenceList> </xenc:EncryptedKey> <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-29B98C291D1FDFB39113352984773591" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><!--Omitted --></wsse:BinarySecurityToken> <ds:Signature Id="Signature-1" 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-2"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue> <!--Omitted --> </ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> <!--Omitted --> </ds:SignatureValue> <ds:KeyInfo Id="KeyId-29B98C291D1FDFB39113352984773792"> <wsse:SecurityTokenReference wsu:Id="STRId-29B98C291D1FDFB39113352984773893" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsse:Reference URI="#CertId-29B98C291D1FDFB39113352984773591" 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> <saml:Assertion ID="_54d0c8395de26c3e44730df2c9e8d3e9" IssueInstant="2012-02-17T10:40:36.806Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:Issuer>CN=test_client</saml:Issuer> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#_54d0c8395de26c3e44730df2c9e8d3e9"> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue> <!--Omitted --> </DigestValue> </Reference> </SignedInfo> <SignatureValue> <!--Omitted --> </SignatureValue> <KeyInfo> <X509Data> <X509Certificate> <!--Omitted --> </X509Certificate> </X509Data> </KeyInfo> </Signature> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"> joe.bloggs@facility.ie </saml:NameID> </saml:Subject> <saml:Conditions NotBefore="2012-02-17T10:40:21.806Z" NotOnOrAfter="2012-02-17T10:41:06.806Z"/> </saml:Assertion> <wsa:Action SOAP-ENV:mustUnderstand="1">http://www.xxxxxxx.xxx/ws/schemas/xxxxxx1/xxxx/xxxxxxxxxxxxxx</wsa:Action> <wsa:MessageID SOAP-ENV:mustUnderstand="1">uuid:bffc27ba-68d9-44e6-b1f0-e2f852df7715</wsa:MessageID> </SOAP-ENV:Header> <SOAP-ENV:Body wsu:Id="id-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <xenc:EncryptedData Id="EncDataId-3" Type="http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Reference URI="#EncKeyId-29B98C291D1FDFB39113352984774895"/> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue> <!--Omitted --> </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

This is as close as I got with my WCF client. I can immediately decide that the <o:SecurityTokenReference> element should contain the Issuer and the Serial Number, instead it contains the KeyIdentifier element?

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1" u:Id="_3"/> <a:MessageID u:Id="_4">urn:uuid:fc8ef84b-dbf5-4150-a0c3-d4cc986333d1</a:MessageID> <ActivityId CorrelationId="a9e1fec4-32bc-4633-909e-3d601c809b3c" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">d1909115-8922-46f3-a96c-db15bf91c599</ActivityId> <a:ReplyTo u:Id="_5"> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo27oY4/3mnBOry0YL4StqvcAAAAA0UM+eVt4fU2AOe9/B3lPDZNf/2HmAuNEvzAoW0eKVSUACQAA</VsDebuggerCausalityData> <a:To s:mustUnderstand="1" u:Id="_6">https://localhost:8089/ws</a:To> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="uuid-e5592f06-32af-40fb-996e-a0a469c7ed5e-2"> <u:Created>2012-04-24T20:41:50.447Z</u:Created> <u:Expires>2012-04-24T20:46:50.447Z</u:Expires> </u:Timestamp> <e:EncryptedKey Id="uuid-e5592f06-32af-40fb-996e-a0a469c7ed5e-1" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <o:SecurityTokenReference> <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">lU10DQn4lSpE4fRpE9gslm5QDt0=</o:KeyIdentifier> </o:SecurityTokenReference> </KeyInfo> <e:CipherData> <e:CipherValue> <!--Omitted--> </e:CipherValue> </e:CipherData> <e:ReferenceList> <e:DataReference URI="#_2"/> <e:DataReference URI="#_7"/> <e:DataReference URI="#_8"/> </e:ReferenceList> </e:EncryptedKey> <o:BinarySecurityToken u:Id="uuid-fad0c01f-ab4b-4a5f-bec6-93aa8c2d5a52-1" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"><!--Omitted--></o:BinarySecurityToken> <e:EncryptedData Id="_7" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <e:CipherData> <e:CipherValue> <!--Omitted--> </e:CipherValue> </e:CipherData> </e:EncryptedData> <e:EncryptedData Id="_8" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <e:CipherData> <e:CipherValue><!--Omitted--></e:CipherValue> </e:CipherData> </e:EncryptedData> </o:Security> </s:Header> <s:Body u:Id="_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <e:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <e:CipherData> <e:CipherValue><!--Omitted--></e:CipherValue> </e:CipherData> </e:EncryptedData> </s:Body> </s:Envelope> uIDPo27oY4 / 3mnBOry0YL4StqvcAAAAA0UM + eVt4fU2AOe9 / B3lPDZNf / 2HmAuNEvzAoW0eKVSUACQAA </ VsDebuggerCausalityData> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1" u:Id="_3"/> <a:MessageID u:Id="_4">urn:uuid:fc8ef84b-dbf5-4150-a0c3-d4cc986333d1</a:MessageID> <ActivityId CorrelationId="a9e1fec4-32bc-4633-909e-3d601c809b3c" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">d1909115-8922-46f3-a96c-db15bf91c599</ActivityId> <a:ReplyTo u:Id="_5"> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo27oY4/3mnBOry0YL4StqvcAAAAA0UM+eVt4fU2AOe9/B3lPDZNf/2HmAuNEvzAoW0eKVSUACQAA</VsDebuggerCausalityData> <a:To s:mustUnderstand="1" u:Id="_6">https://localhost:8089/ws</a:To> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="uuid-e5592f06-32af-40fb-996e-a0a469c7ed5e-2"> <u:Created>2012-04-24T20:41:50.447Z</u:Created> <u:Expires>2012-04-24T20:46:50.447Z</u:Expires> </u:Timestamp> <e:EncryptedKey Id="uuid-e5592f06-32af-40fb-996e-a0a469c7ed5e-1" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <o:SecurityTokenReference> <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">lU10DQn4lSpE4fRpE9gslm5QDt0=</o:KeyIdentifier> </o:SecurityTokenReference> </KeyInfo> <e:CipherData> <e:CipherValue> <!--Omitted--> </e:CipherValue> </e:CipherData> <e:ReferenceList> <e:DataReference URI="#_2"/> <e:DataReference URI="#_7"/> <e:DataReference URI="#_8"/> </e:ReferenceList> </e:EncryptedKey> <o:BinarySecurityToken u:Id="uuid-fad0c01f-ab4b-4a5f-bec6-93aa8c2d5a52-1" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"><!--Omitted--></o:BinarySecurityToken> <e:EncryptedData Id="_7" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <e:CipherData> <e:CipherValue> <!--Omitted--> </e:CipherValue> </e:CipherData> </e:EncryptedData> <e:EncryptedData Id="_8" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <e:CipherData> <e:CipherValue><!--Omitted--></e:CipherValue> </e:CipherData> </e:EncryptedData> </o:Security> </s:Header> <s:Body u:Id="_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <e:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <e:CipherData> <e:CipherValue><!--Omitted--></e:CipherValue> </e:CipherData> </e:EncryptedData> </s:Body> </s:Envelope> 

Using this configuration for WCF custom binding

 <system.serviceModel> <bindings> <customBinding> <binding name="WSHttpBinding_IEnquiryRequest" > <transactionFlow /> <security defaultAlgorithmSuite="TripleDesRsa15" authenticationMode="MutualCertificate" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" requireDerivedKeys="false" > <secureConversationBootstrap authenticationMode="CertificateOverTransport" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" requireDerivedKeys="false" /> </security> <textMessageEncoding messageVersion="Soap11WSAddressing10" /> <!--<mtomMessageEncoding messageVersion="Soap11WSAddressing10" />--> <httpsTransport requireClientCertificate="true" /> </binding> </customBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="certBehaviour"> <clientCredentials> <!-- clientCertificate not defaultCertificate --> <clientCertificate x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" findValue="test_client" /> <serviceCertificate> <defaultCertificate x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" findValue="test_server"/> <authentication revocationMode="NoCheck" certificateValidationMode="None" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <client> <endpoint address="https://localhost:8089/pvs/ws" binding="customBinding" bindingConfiguration="WSHttpBinding_IEnquiryRequest" contract="XXXService.enquiryRequest" name="WSHttpBinding_IEnquiryRequest" behaviorConfiguration="certBehaviour" > <identity> <dns value="test_server"/> </identity> </endpoint> </client> </system.serviceModel> 

I have no idea how to insert a SAML 2.0 statement where it was signed. This is the key release / serial release above, where my main concerns are related to the request.

Any help is appreciated.

+7
source share
3 answers

I used a sample XML template instead of doing all this in code, but this is also possible.

Note. You need to add this message using Custom Encoder - this way you can simply put the SAML marker in the header (only the title elements are signed, not the content)

I'm in a hurry, let me know if you need more information

  private void SignSaml() { RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)SecurityController.ClientCertificate.PrivateKey; //Load the private key from xml file XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(_samlTextWithElementValues); // Create a SignedXml object. SignedXml signedXml = new SignedXml(xmlDocument); //Specify the canonicalization method signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Add the key to the SignedXml document. signedXml.SigningKey = rsaProvider; // Add the x509 data to the signature KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoClause = new KeyInfoX509Data(SecurityController.ClientCertificate, X509IncludeOption.None); keyInfoClause.AddCertificate(SecurityController.ClientCertificate); keyInfo.AddClause(keyInfoClause); signedXml.KeyInfo = keyInfo; // Create a reference to be signed. Reference reference = new Reference("#_54d0c8395de26c3e44730df2c9e8d3e9"); //reference.Uri = ; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); reference.AddTransform(new XmlDsigExcC14NTransform()); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true)); _samlSignedWithCertificate = xmlDocument.InnerXml; } 

Added configuration on request

 <customBinding> <binding name="BINDING" > <transactionFlow /> <security defaultAlgorithmSuite="TripleDesRsa15" authenticationMode="MutualCertificate" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" requireDerivedKeys="false" messageProtectionOrder="SignBeforeEncrypt"> <secureConversationBootstrap authenticationMode="CertificateOverTransport" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" requireDerivedKeys="false" /> </security> <httpsTransport requireClientCertificate="true" /> </binding> </customBinding> 
0
source

Was able to get there at the end using Yaron on WCF forums

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/9a1db0bb-d632-4f11-80b4-fab78be3a3ee

It was difficult, but got there to think that I was going to write it from scratch at some point!

+2
source

WIF supports the SAML 2.0 token format if you are not using XP.

0
source

All Articles