2012-04-24 15 views
7

Abbiamo un partner commerciale che ci richiede di creare un messaggio di richiesta di servizio con un'asserzione SAML 2.0. Il partner ha fornito due certificati e un'imbracatura di test per il loro servizio web JAVA.Il client WCF utilizza il servizio Web JAVA: dovrei usare WCF o semplicemente creare un parser/fabbrica di messaggi personalizzato?

Ho creato un client WCF con un CustomBinding per tentare di ricreare la richiesta e consumare il servizio, ma mi sento così frustrato dalle sfumature di WCF (e dalla mancanza di supporto intrinseco per SAML 2.0) I ' Mi chiedo se sia meglio usare qualcosa come uno WebClient o HttpWebRequest e crittografare/creare & firmando la richiesta web XML e facendo lo stesso per la risposta. So che c'è molto lavoro su questo, ma almeno sarei in pieno controllo.

tuo consiglio sarebbe molto apprezzato, quello che sto lavorando con è visualizzato sotto

Nota: mi è stato fornito con un cablaggio di prova SoapUI per il servizio Java

Il venditore mi ha fornito con questa richiesta (se riceve SoapUI ed estratta con 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">[email protected]</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> 

questo è il più vicino I'v e ottenuto con il mio client WCF. I problemi che posso immediatamente sono che l'elemento deve contenere l'emittente e la seriale, invece contiene un elemento KeyIdentifier?

<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> 

Con questa configurazione per il WCF customBinding

<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> 

Non ho idea di come inserire l'asserzione SAML 2.0 in là prima di essere firmato. Quello e il problema principale Issuer/seriale sopra è dove i miei problemi principali si trovano con la richiesta.

Qualsiasi aiuto apprezzato

+0

Se si riesce a farlo funzionare con WCF, sicuramente andare con quella. Puoi aggiungere le tue intestazioni degli indirizzi personalizzate, dovevo farlo per un client WSF di sicurezza WCF. Oppure prova un altro framework per client di servizi Web. Non implementare il proprio a meno che non sia l'ultima risorsa. – jrummell

+0

Hai provato a creare un riferimento al servizio _classic_ invece del nuovo riferimento al servizio standard? Vedere la sezione [Come aggiungere un riferimento a un servizio Web] (http://msdn.microsoft.com/en-us/library/bb628649.aspx) per ulteriori informazioni. Ho trovato il proxy generato da questo metodo per essere più compatibile con i servizi non .NET e ho avuto più fortuna modificandoli quando necessario. –

+0

Grazie Joshua. Suppongo che la classe del proxy generi solo i contratti di condivisione dei dati, ecc. - Ho già funzionato OK, penso. Il problema è con l'intestazione SOAP che non è contenuta nel WSDL – StickyMcGinty

risposta

0

Ho usato un modello XML di esempio invece di fare tutto in codice, ma anche questo è possibile.

Nota: È necessario aggiungere questo al messaggio utilizzando un Custom Encoder - in questo modo si può solo fessura nel token SAML nell'intestazione (solo elementi di intestazione è effettuato l'accesso, non il contenuto)

Sono in un po 'di fretta, fatemi sapere se avete bisogno di più informazioni

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; 
    } 

Aggiunto config secondo la richiesta

<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

WIF supporti SAML 2.0 formato del token se non si esegue su XP.

+0

Grazie. Ho guardato la documentazione di WIF e non è la migliore. Dare un altro sguardo – StickyMcGinty

2

è stato in grado di arrivare alla fine, con l'aiuto di Yaron corso sul forum WCF

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

era difficile, ma arrivati ​​alla fine, di pensare che stavo per scriverlo da zero a un punto!

+0

Ciao @StickyMcGinty, ho la stessa situazione. Sarebbe possibile per te condividere un esempio della tua soluzione con il token di sicurezza? – Quintium

+0

Ho semplicemente creato il token SAML di esempio tramite XML e l'ho firmato, campione sotto – StickyMcGinty

+0

Grazie per la risposta. Darei un'occhiata a questo. Prima di rispondere, siamo stati in grado di far funzionare un client, ma ora riscontriamo problemi su un altro servizio Web Java a cui non piace il modo in cui WCF fa riferimento a un'intestazione personalizzata nel blocco della firma. Dove SoapUI crea una "InclusiveNamespaces PrefixList" nell'intestazione all'interno del blocco di riferimento del corpo. – Quintium

Problemi correlati