2013-02-06 12 views
11

सारांश: मैं एक .NET 4.0 WCF क्लाइंट पर काम कर रहा हूँ एक वेब सेवा का उपभोग करने के (डेटापावर, दूसरी तरफ जावा सेवा) SOAP 1.1 और डब्ल्यूएस-सुरक्षा 1.0 का उपयोग कर। डब्ल्यूसीएफ क्लाइंट को परिवहन परत पर पारस्परिक प्रमाणीकरण के लिए क्लाइंट प्रमाणपत्र लागू करना होगा। संदेश निकाय को एक अलग सेवा/हस्ताक्षर प्रमाणपत्र का उपयोग करके हस्ताक्षर करने की आवश्यकता है। एसओएपी हेडर में पासवर्ड डाइजेस्ट के साथ उपयोगकर्ता नाम टोकन भी शामिल होना चाहिए और इसमें नॉन और बनाए गए टैग शामिल हैं।WCF SOAP 1.1 और WS-सुरक्षा 1.0, क्लाइंट प्रमाणपत्र परिवहन प्राधिकार, संदेश के मुख्य भाग हस्ताक्षर के लिए सेवा प्रमाणपत्र, UsernameToken, पासवर्ड डाइजेस्ट, Nonce

मैं मूल एचटीटीपी बाइंडिंग के साथ डब्ल्यूएसई 3.0 का उपयोग करके इस वेब सेवा का उपभोग करने में सक्षम हूं। लेकिन मैं WSHttp बाइंडिंग या कस्टम बाइंडिंग का उपयोग कर डब्ल्यूसीएफ के साथ इसे लागू करने में अब तक सफल नहीं रहा हूं। मैंने सभी सुरक्षा बाध्यकारी तत्वों की कोशिश की है और अब तक कोई भाग्य नहीं है।

मैं यहां से उपयोगकर्ता नामांकित लाइब्रेरी का भी उपयोग कर रहा हूं (http://blogs.msdn.com/b/aszego/archive/2010/06/24/usernametoken-profile-vs-wcf.aspx) इसलिए मैं SOAP शीर्षलेख में उपयोगकर्ता नाम टोकन में पासवर्ड पाचन/nonce/बनाया जा सकता हूं। मैं दोनों क्लाइंट प्रमाणपत्र और सेवा प्रमाण पत्र भरा हुआ:

मैं वर्तमान में SecurityBindingElement.CreateMutualCertificateBindingElement उपयोग कर रहा हूँ मैं भी इस तरह के AsymmetricSecurityBindingElement के रूप में कई अन्य लोगों की कोशिश की है, TransportSecurityBindingElement आदि

प्रमाणपत्र (बाहर नीचे दिए गए कोड में टिप्पणी की) एमएमसी का उपयोग कर प्रमाणपत्र स्टोर में (मैं विंडोज 7 बीटीडब्ल्यू पर हूं।) क्लाइंट प्रमाण पत्र और सेवा प्रमाण दोनों में निजी कुंजी हैं। मैंने पीएफएक्स फ़ाइलों को स्थानीयमाचिन/पर्सनल, लोकलमाचिन/रूट और लोकलमाचिन/ट्रस्टेड लोगों में लोड किया है। मैंने "आईआईएस ऐप पूल/DefaultAppPool" खाते को अनुमति देने के लिए FindPrivateKey/ICACLS भी चलाया है। हालांकि इनमें से कोई भी इससे कोई फर्क नहीं पड़ता क्योंकि मैं अपनी मशीन से डब्लूएसई 3.0 कोड चला सकता हूं और यह बिना किसी प्रमाण के मुद्दों के काम करता है।

आदेश चलाएँ:

FindPrivateKey.exe My LocalMachine -t "thumbprint of client cert" 
FindPrivateKey.exe My LocalMachine -t "thumbprint of service cert" 
icacls C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\{privateKeyOfClientCert} /grant "IIS AppPool\DefaultAppPool":R  <<Successfully processed 1 files; Failed processing 0 files>> 
icacls C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\{privateKeyOfServiceCert} /grant "IIS AppPool\DefaultAppPool":R  <<Successfully processed 1 files; Failed processing 0 files>> 

WCF मुद्दा: मैं वर्तमान में DataPower प्रवेश द्वार से वापस एक "अधिकार के साथ SSL/TLS के लिए सुरक्षित चैनल स्थापित नहीं कर सका x.x.com '" संदेश प्राप्त होता है। मुझे लगता है कि ऐसा इसलिए हो सकता है क्योंकि गेटवे सेवा प्रमाण पत्र ले रहा है और क्लाइंट प्रमाण पत्र का उपयोग करने के बजाय क्लाइंट प्रमाणीकरण के लिए इसका उपयोग कर रहा हूं। मैं यह कह रहा हूं क्योंकि जब मैं एंडपॉइंट के लिए DNS पहचान निर्दिष्ट नहीं करता हूं, तो मुझे एक संदेश वापस आ जाता है कि गेटवे DNS पहचान को "सेवा/हस्ताक्षर प्रमाण पत्र का विषय नाम" होने की उम्मीद कर रहा है।

डब्ल्यूसीएफ द्वारा उत्पन्न एसओएपी अनुरोध यहां दिया गया है जो उपर्युक्त त्रुटि दे रहा है। डब्ल्यूसीएफ एसओएपी अनुरोध डब्ल्यूएसई एसओएपी अनुरोध के समान दिखता है। एसएसएल/ट्रांसपोर्ट परत पर प्रमाणित समस्या के कारण उपरोक्त त्रुटि सबसे अधिक हो रही है।

WCF सोप अनुरोध:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<s:Header> 
    <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-8533d9a5-865e-4a4b-a750-fadb7c1ce36c-1"> 
      <u:Created>2013-02-06T20:53:04.679Z</u:Created> 
      <u:Expires>2013-02-06T20:58:04.679Z</u:Expires> 
     </u:Timestamp> 
     <o:BinarySecurityToken u:Id="uuid-0bab08ce-3e3b-4360-a44b-694b06a3dd67-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">Removed Service Cert Encoded Value</o:BinarySecurityToken> 
     <wsse:UsernameToken wsu:Id="7843ab92-f69a-4d00-a5ba-117e32a74f49" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <wsse:Username>USER_Removed</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">XXX=</wsse:Password> 
      <wsse:Nonce>XXX==</wsse:Nonce> 
      <wsu:Created>2013-02-06T20:53:04Z</wsu:Created> 
     </wsse:UsernameToken> 
     <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
      <SignedInfo> 
       <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod> 
       <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod> 
       <Reference URI="#_1"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#uuid-8533d9a5-865e-4a4b-a750-fadb7c1ce36c-1"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#7843ab92-f69a-4d00-a5ba-117e32a74f49"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
      </SignedInfo> 
      <SignatureValue>XXXLongXXX=</SignatureValue> 
      <KeyInfo> 
       <o:SecurityTokenReference> 
        <o:Reference URI="#uuid-0bab08ce-3e3b-4360-a44b-694b06a3dd67-2"></o:Reference> 
       </o:SecurityTokenReference> 
      </KeyInfo> 
     </Signature> 
    </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"> 
    <ping xmlns="https://x.x.com/xxx/v1"> 
     <pingRequest xmlns="">hello</pingRequest> 
    </ping> 
</s:Body> 

WSE 3।0 सोप अनुरोध (यह काम करता है):

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<soap:Header> 
    <wsa:Action wsu:Id="Id-4271fb72-464a-467d-ab1f-4d32542e20f0"/> 
    <wsa:MessageID wsu:Id="Id-11657f64-d856-47d8-b600-d5379fb91a0d">urn:uuid:ff8becb7-74c2-4844-ab46-8ae23f1355a7</wsa:MessageID> 
    <wsa:ReplyTo wsu:Id="Id-40b2e6e8-e67b-4a6c-a545-071ce0f0107a"> 
     <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address> 
    </wsa:ReplyTo> 
    <wsa:To wsu:Id="Id-d5e0b488-6f8a-479c-940d-2b85833dbc66">https://x.x.com/xxx/v1</wsa:To> 
    <wsse:Security soap:mustUnderstand="1"> 
     <wsu:Timestamp wsu:Id="Timestamp-68476551-5c58-4a47-967b-54ec18257b1b"> 
      <wsu:Created>2013-02-06T19:38:39Z</wsu:Created> 
      <wsu:Expires>2013-02-06T19:43:39Z</wsu:Expires> 
     </wsu:Timestamp> 
     <wsse:UsernameToken wsu:Id="SecurityToken-e5f65166-a825-48cb-a939-8e515a637e01"> 
      <wsse:Username>USER_Removed</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">XXX=</wsse:Password> 
      <wsse:Nonce>XXX==</wsse:Nonce> 
      <wsu:Created>2013-02-06T19:38:39Z</wsu:Created> 
     </wsse:UsernameToken> 
     <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
      <SignedInfo> 
       <ds:CanonicalizationMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
       <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 
       <Reference URI="#Id-4271fb72-464a-467d-ab1f-4d32542e20f0"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#Id-11657f64-d856-47d8-b600-d5379fb91a0d"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#Id-40b2e6e8-e67b-4a6c-a545-071ce0f0107a"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#Id-d5e0b488-6f8a-479c-940d-2b85833dbc66"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#Timestamp-68476551-5c58-4a47-967b-54ec18257b1b"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
       <Reference URI="#Id-6f76e50e-932c-4878-bbc0-3ef4c8a36990"> 
        <Transforms> 
         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        </Transforms> 
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
        <DigestValue>XXX=</DigestValue> 
       </Reference> 
      </SignedInfo> 
      <SignatureValue>XXXLongXXX=</SignatureValue> 
      <KeyInfo> 
       <wsse:SecurityTokenReference> 
        <wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" 
             EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">XXX=</wsse:KeyIdentifier> 
       </wsse:SecurityTokenReference> 
      </KeyInfo> 
     </Signature> 
    </wsse:Security> 
</soap:Header> 
<soap:Body wsu:Id="Id-6f76e50e-932c-4878-bbc0-3ef4c8a36990"> 
    <ping xmlns="https://x.x.com/xxx/v1"> 
     <pingRequest xmlns="">hello</pingRequest> 
    </ping> 
</soap:Body> 

यहाँ config के सभी है, मुझे पता है मैं गलत क्या कर रहा हूँ तो कृपया!

डब्ल्यूसीएफ web.config: मैंने web.config से सब कुछ हटा दिया क्योंकि मैं कोड में सभी कॉन्फ़िगरेशन कर रहा हूं। कोड में

WCF config:

var proxy = GetProxy(); 
pingResponseMessage resp = proxy.ping("hello"); 
lblStatus.Text = resp.status.ToString(); 

private XXXClient GetProxy() 
{ 

    System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return true; }; 

    XXXClient proxy = new XXXClient(GetCustomBinding(), new EndpointAddress(new Uri("https://xxx"), EndpointIdentity.CreateDnsIdentity("I am forced to put the signing cert subject here, nothing else works"), new AddressHeaderCollection())); 

    proxy.Endpoint.Behaviors.Remove(typeof(ClientCredentials)); 
    proxy.Endpoint.Behaviors.Add(new UsernameClientCredentials(new UsernameInfo(@"USER_Removed", "X"))); 

    proxy.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "REMOVED"); 
    proxy.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "REMOVED"); 
    proxy.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; 

    return proxy; 
} 

private Binding GetCustomBinding() 
{ 
    //TransportSecurityBindingElement secBE = SecurityBindingElement.CreateCertificateOverTransportBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10); 
    //AsymmetricSecurityBindingElement secBE = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10); 
    //secBE.InitiatorTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient, RequireDerivedKeys = false, X509ReferenceStyle = X509KeyIdentifierClauseType.SubjectKeyIdentifier }; 
    //secBE.RecipientTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.AlwaysToInitiator, RequireDerivedKeys = false, X509ReferenceStyle = X509KeyIdentifierClauseType.SubjectKeyIdentifier }; 
    //secBE.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt; 
    //secBE.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters() { InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient, RequireDerivedKeys = false }); 
    //secBE.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters(X509KeyIdentifierClauseType.SubjectKeyIdentifier, SecurityTokenInclusionMode.Never) { InclusionMode = SecurityTokenInclusionMode.Never, RequireDerivedKeys = false, X509ReferenceStyle = X509KeyIdentifierClauseType.SubjectKeyIdentifier }); 
    //secBE.ProtectionTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient }; 
    //secBE.DefaultAlgorithmSuite = new CustomSecurityAlgorithm(); 

    SecurityBindingElement secBE = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10); 
    secBE.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10; 
    secBE.EndpointSupportingTokenParameters.Signed.Add(new UsernameTokenParameters() { InclusionMode= SecurityTokenInclusionMode.AlwaysToRecipient, ReferenceStyle = SecurityTokenReferenceStyle.External, RequireDerivedKeys = false }); 
    secBE.SecurityHeaderLayout = SecurityHeaderLayout.Strict; 
    //secBE.AllowInsecureTransport = false; 
    //secBE.AllowSerializedSigningTokenOnReply = false; 
    secBE.EnableUnsecuredResponse = true; 
    secBE.IncludeTimestamp = true; 
    secBE.SetKeyDerivation(false); 

    TextMessageEncodingBindingElement textEncBE = new TextMessageEncodingBindingElement(MessageVersion.Soap11, System.Text.Encoding.UTF8); 

    HttpsTransportBindingElement httpsBE = new HttpsTransportBindingElement(); 
    httpsBE.RequireClientCertificate = true; 
    //httpsBindingElement.AllowCookies = false; 
    //httpsBindingElement.AuthenticationScheme = System.Net.AuthenticationSchemes.Basic; 
    httpsBE.BypassProxyOnLocal = false; 
    httpsBE.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; 
    //httpsBindingElement.KeepAliveEnabled = false; 
    httpsBE.TransferMode = TransferMode.Buffered; 
    httpsBE.UseDefaultWebProxy = true; 

    CustomBinding myBinding = new CustomBinding(); 
    myBinding.Elements.Add(secBE); 
    myBinding.Elements.Add(textEncBE); 
    myBinding.Elements.Add(httpsBE); 

    return myBinding; 
} 

मैं के बाद से मैं केवल संदेश के मुख्य भाग हस्ताक्षर करने की आवश्यकता ServiceContract और OperationContracts पर ProtectionLevel.Sign जोड़ दिया है। हालांकि मुझे इसे अभी तक सत्यापित करने के लिए अभी तक नहीं मिला है।

[System.ServiceModel.ServiceContractAttribute(Namespace = "https://x.x.com/xxx/v1", ConfigurationName = "x.x", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)] 
public interface XXXService { 
    [System.ServiceModel.OperationContractAttribute(Action = "", ReplyAction = "*", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)] 
    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)] 
    [return: System.ServiceModel.MessageParameterAttribute(Name="return")] 
    XXX.pingResponse ping(XXX.ping request); 

[System.ServiceModel.ServiceContractAttribute(Namespace = "https://x.x.com/xxx/v1", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)] 
public partial class XXXClient : System.ServiceModel.ClientBase<XXXService> { 
    [System.ServiceModel.OperationContractAttribute(Action = "", ReplyAction = "*", ProtectionLevel = System.Net.Security.ProtectionLevel.Sign)] 
    public XXX.pingResponseMessage ping(string pingRequest) { 

मैं web.config PII डेटा

(for pii, also added <machineSettings enableLoggingKnownPii="true" /> under <system.serviceModel> to C:\Windows\Microsoft.NET\Framework\vX\CONFIG\machine.config) 

<system.serviceModel> 
<diagnostics> 
    <messageLogging logKnownPii="true" logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000"/> 
</diagnostics> 
</system.serviceModel> 
<system.diagnostics> 
<sources> 
    <source name="System.ServiceModel.MessageLogging" logKnownPii="true"> 
    <listeners> 
     <add initializeData="C:\trace.log" type="System.Diagnostics.XmlWriterTraceListener" name="messages"/> 
    </listeners> 
    </source> 
</sources> 
</system.diagnostics> 

सहित पूरे साबुन के प्रवेश की अनुमति देने के लिए नीचे दी गई जोड़ दिया है ============== =

WSE 3.0 (कार्य config और कोड): web.config:

<system.serviceModel> 
<bindings> 
    <basicHttpBinding> 
    <binding name="myBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> 
     <security mode="Transport"> 
     <transport clientCredentialType="None" proxyCredentialType="None" realm=""/> 
     <message clientCredentialType="UserName" algorithmSuite="Default"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
<client> 
    <endpoint address="https://x.x.com/xxx/v1" binding="basicHttpBinding" bindingConfiguration="myBinding" contract="XXXService" name="XXX"/> 
</client> 
</system.serviceModel> 
<appSettings> 
<add key="XXXImplService" value="https://x.x.com/xxx/v1"/> 
</appSettings> 

... और WSE3 कोड:

var proxy = new XXXImplServiceWse(); 

UsernameToken usernameToken = new UsernameToken(@"USER_Removed", "X"); 
proxy.RequestSoapContext.Security.Tokens.Add(usernameToken); 

X509Certificate2 mutualCert = LoadCertFromStore(StoreLocation.LocalMachine, StoreName.My, "Client Cert Subject Name"); 
proxy.ClientCertificates.Add(mutualCert); 

X509Certificate2 signCert = LoadCertFromStore(StoreLocation.LocalMachine, StoreName.My, "Service Cert Subject Name"); 

X509SecurityToken signatureToken = new X509SecurityToken(signCert); 

MessageSignature signature = new MessageSignature(signatureToken); // <!-- IS THIS SAME AS THIS STEP IN WCF: secBE.EndpointSupportingTokenParameters.Signed.Add(new UsernameTokenParameters()) --> 

proxy.RequestSoapContext.Security.Elements.Add(signature); 

==========

तो, मैं कैसे WCF करने के लिए ऊपर WSE 3.0 कोड में परिवर्तित?

+0

जब आप डब्लूएसई 3.0 में समाधान समाधान करते हैं तो आप पहली जगह क्यों परिवर्तित करना चाहते हैं? डब्ल्यूएसई कोड में आपके प्रश्न के लिए: कोई एंडपॉइंट समर्थन टोकन पूरी तरह से अलग सुविधा नहीं है। Btw। क्या आपको डब्ल्यूएस-एड्रेसिंग की भी आवश्यकता है (इसका उपयोग डब्ल्यूएसई क्लाइंट में किया जाता है)। –

+1

हमारे पास एक क्लाइंट है जो जोर देता है कि हम उन्हें डब्ल्यूसीएफ संस्करण प्रदान करते हैं क्योंकि वे कहते हैं कि डब्लूएसई 3.0 "पुरानी तकनीक" है ... मुझे लगता है कि मामलों को संबोधित नहीं करना है, लेकिन निश्चित रूप से अनुरूपता के लिए, हम इसे सोप 11WSAddressing10 – Jawad

+0

रखेंगे सप्ताहांत के दौरान इस समस्या को देखें - मुझे खुद में दिलचस्पी है लेकिन तैयार रहें कि डब्ल्यूसीएफ के लिए कोई समाधान नहीं हो सकता है (मैन्युअल रूप से लेखन सुरक्षा को छोड़कर) - डब्ल्यूसीएफ में डब्ल्यूएसई 3.0 में पहले उपलब्ध सभी विकल्पों को शामिल नहीं किया गया है। जिज्ञासा से बाहर: क्या आपके पास डब्ल्यूएस-सिक्योरिटी पॉलिसी (आमतौर पर डब्लूएसडीएल या जावा सेवा परिनियोजन का हिस्सा है) या नमूना अनुरोध और सेवा के लिए प्रतिक्रिया (डब्लूएसई द्वारा उत्पन्न नहीं बल्कि जावा क्लाइंट) है? –

उत्तर

6

मैं अपने मुद्दे को हल करने और निम्नलिखित डब्ल्यूसीएफ कस्टमबी का उपयोग कर डेटापावर (आईबीएम Xi50) वेब सेवा गेटवे से कनेक्ट करने में सक्षम था इंडिंग (सर्टिफिकेटऑवर ट्रांस्पोर्ट) और कस्टम क्रेडेंशियल्स (उपयोगकर्ता नाम, पासवर्ड डायजेस्ट के साथ टोकन, परिवहन प्रमाणीकरण के लिए क्लाइंट प्रमाण पत्र और संदेश निकाय हस्ताक्षर के लिए सेवा प्रमाण पत्र।) मुझे यकीन नहीं है कि इस मुद्दे को वास्तव में क्या तय किया गया है, लेकिन यहां मेरा कामकाजी डब्ल्यूसीएफ कोड है! मुझे उम्मीद है कि यह उन लोगों की मदद करता है जो समान स्थिति में हैं।

कृपया सत्यापित करें कि डेटापावर Xi50 गेटवे भी डब्ल्यूसीएफ के लिए कॉन्फ़िगर किया गया है। आईबीएम से: "SSL के साथ BasicHttp बाइंडिंग का उपयोग करते समय: आप किसी भी ट्रांसपोर्ट बाइंडिंग दावे के लिए सिफर चेक अक्षम करने के लिए अक्षम-एसएसएल-सिफर-चेक पैरामीटर का उपयोग कर सकते हैं। मूल ऑथ हेडर वेब सेवाओं प्रॉक्सी में डिफ़ॉल्ट रूप से समर्थित नहीं है। एक कस्टम कॉन्फ़िगरेशन WWF के साथ इंटर-ऑप करने के लिए WWW-प्रमाणीकरण हेडर को इंजेक्ट करने के लिए ऑन-त्रुटि नियम आवश्यक है। " विवरण के लिए, यहां जाएं: https://publib.boulder.ibm.com/infocenter/ieduasst/v1r1m0/index.jsp?topic=/com.ibm.iea.wdatapower/wdatapower/1.0/xa35/380DataPowerWCFIntegration/player.html

करें कि आप अपने सेवा अनुबंध पर ProtectionLevel.Sign निर्धारित किया है अगर आप चाहते हैं कि आपके संदेश के मुख्य भाग केवल हस्ताक्षर किए (और नहीं एन्क्रिप्ट किया गया।)

डीएनएस पहचान है, जो मैंने पहले के साथ मुद्दों था के लिए, मैं अब कर रहा था मेरे क्लाइंट प्रमाणपत्र विषय का नाम दें - इससे पहले यह काम नहीं करेगा।

मेरे पास मेरे web.config में कोई कॉन्फ़िगरेशन नहीं है। के लिए (? आपसी) परिवहन परत पर प्रमाणीकरण क्लाइंट प्रमाणपत्र सेट -

private ClientProxy GetProxy() 
{ 
    XXXServiceClient proxy = new XXXServiceClient(GetCustomBinding(), new EndpointAddress(new Uri("<<GatewayURLHere>>"), EndpointIdentity.CreateDnsIdentity("<<DNS or Client Cert Subject Name>>"), new AddressHeaderCollection())); 
    proxy.Endpoint.Behaviors.Remove(typeof(ClientCredentials)); 
    proxy.Endpoint.Behaviors.Add(new CustomCredentials(<clientCertHere>, <signingCertHere>)); 
    proxy.ClientCredentials.UserName.UserName = @"XXX"; 
    proxy.ClientCredentials.UserName.Password = "yyy"; 
    return proxy; 
} 

private Binding GetCustomBinding() 
{ 
    TransportSecurityBindingElement secBE = SecurityBindingElement.CreateCertificateOverTransportBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10); 
    secBE.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.Never, RequireDerivedKeys = false }); 
    secBE.EnableUnsecuredResponse = true; 
    secBE.IncludeTimestamp = true; 
    TextMessageEncodingBindingElement textEncBE = new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressingAugust2004, System.Text.Encoding.UTF8); 
    HttpsTransportBindingElement httpsBE = new HttpsTransportBindingElement(); 
    httpsBE.RequireClientCertificate = true; 

    CustomBinding myBinding = new CustomBinding(); 
    myBinding.Elements.Add(secBE); 
    myBinding.Elements.Add(textEncBE); 
    myBinding.Elements.Add(httpsBE); 

    return myBinding; 
} 

यहाँ है मेरी CustomCredentials वर्ग है कि मैं ऊपर उल्लेख किया UsernameToken पुस्तकालय सहित अनेक स्रोतों से एक साथ रखा:

यहाँ प्रॉक्सी CustomBinding उपयोग कर रहा है , संदेश निकाय और उपयोगकर्ता नाम पर हस्ताक्षर करने के लिए सेवा/हस्ताक्षर प्रमाणपत्र SOAP शीर्षलेख में पासवर्ड डाइजेस्ट के साथ टोकन:

using System; 
using System.IdentityModel.Selectors; 
using System.IdentityModel.Tokens; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Description; 
using System.ServiceModel.Security; 
using System.Text; 

namespace XXX_WCF 
{ 
    public class CustomCredentials : ClientCredentials 
    { 
     private X509Certificate2 clientAuthCert; 
     private X509Certificate2 clientSigningCert; 

     public CustomCredentials() : base() { } 

     public CustomCredentials(CustomCredentials other) 
      : base(other) 
     { 
      clientSigningCert = other.clientSigningCert; 
      clientAuthCert = other.clientAuthCert; 
     } 

     protected override ClientCredentials CloneCore() 
     { 
      CustomCredentials scc = new CustomCredentials(this); 
      return scc; 
     } 

     public CustomCredentials(X509Certificate2 ClientAuthCert, X509Certificate2 ClientSigningCert) 
      : base() 
     { 
      clientAuthCert = ClientAuthCert; 
      clientSigningCert = ClientSigningCert; 
     } 

     public X509Certificate2 ClientAuthCert 
     { 
      get { return clientAuthCert; } 
      set { clientAuthCert = value; } 
     } 

     public X509Certificate2 ClientSigningCert 
     { 
      get { return clientSigningCert; } 
      set { clientSigningCert = value; } 
     } 

     public override SecurityTokenManager CreateSecurityTokenManager() 
     { 
      return new CustomTokenManager(this); 
     } 
    } 

    public class CustomTokenManager : ClientCredentialsSecurityTokenManager 
    { 
     private CustomCredentials custCreds; 

     public CustomTokenManager(CustomCredentials CustCreds) 
      : base(CustCreds) 
     { 
      custCreds = CustCreds; 
     } 

     public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) 
     { 
      if (tokenRequirement.TokenType == SecurityTokenTypes.X509Certificate) 
      { 
       x509CustomSecurityTokenProvider prov; 
       object temp = null; 
       TransportSecurityBindingElement secBE = null; 

       if (tokenRequirement.Properties.TryGetValue("http://schemas.microsoft.com/ws/2006/05/servicemodel/securitytokenrequirement/SecurityBindingElement", out temp)) 
       { 
        secBE = (TransportSecurityBindingElement)temp; 
       } 

       if (secBE == null) 
        prov = new x509CustomSecurityTokenProvider(custCreds.ClientAuthCert); 
       else 
        prov = new x509CustomSecurityTokenProvider(custCreds.ClientSigningCert); 
       return prov; 
      } 

      return base.CreateSecurityTokenProvider(tokenRequirement); 
     } 

     public override System.IdentityModel.Selectors.SecurityTokenSerializer CreateSecurityTokenSerializer(System.IdentityModel.Selectors.SecurityTokenVersion version) 
     { 
      return new CustomTokenSerializer(System.ServiceModel.Security.SecurityVersion.WSSecurity10); 
     } 
    } 

    class x509CustomSecurityTokenProvider : SecurityTokenProvider 
    { 
     private X509Certificate2 clientCert; 

     public x509CustomSecurityTokenProvider(X509Certificate2 cert) 
      : base() 
     { 
      clientCert = cert; 
     } 

     protected override SecurityToken GetTokenCore(TimeSpan timeout) 
     { 
      return new X509SecurityToken(clientCert); 
     } 
    } 

    public class CustomTokenSerializer : WSSecurityTokenSerializer 
    { 
     public CustomTokenSerializer(SecurityVersion sv) : base(sv) { } 

     protected override void WriteTokenCore(System.Xml.XmlWriter writer, System.IdentityModel.Tokens.SecurityToken token) 
     { 
      if (writer == null) 
      { 
       throw new ArgumentNullException("writer"); 
      } 
      if (token == null) 
      { 
       throw new ArgumentNullException("token"); 
      } 

      if (token.GetType() == new UserNameSecurityToken("x", "y").GetType()) 
      { 
       UserNameSecurityToken userToken = token as UserNameSecurityToken; 

       if (userToken == null) 
       { 
        throw new ArgumentNullException("userToken: " + token.ToString()); 
       } 

       string tokennamespace = "o"; 

       DateTime created = DateTime.Now; 
       string createdStr = created.ToString("yyyy-MM-ddThh:mm:ss.fffZ"); 
       string phrase = Guid.NewGuid().ToString(); 
       string nonce = GetSHA1String(phrase); 
       string password = GetSHA1String(nonce + createdStr + userToken.Password); 
       //string password = userToken.Password; 

       writer.WriteStartElement(tokennamespace, "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 
       writer.WriteAttributeString("u", "Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", token.Id); 
       writer.WriteElementString(tokennamespace, "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", userToken.UserName); 
       writer.WriteStartElement(tokennamespace, "Password", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 
       writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"); 
       writer.WriteValue(password); 
       writer.WriteEndElement(); 
       writer.WriteStartElement(tokennamespace, "Nonce", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 
       writer.WriteAttributeString("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"); 
       writer.WriteValue(nonce); 
       writer.WriteEndElement(); 
       writer.WriteElementString(tokennamespace, "Created", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", createdStr); 
       writer.WriteEndElement(); 
       writer.Flush(); 
      } 
      else 
      { 
       base.WriteTokenCore(writer, token); 
      } 
     } 

     protected string GetSHA1String(string phrase) 
     { 
      SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider(); 
      byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase)); 
      return Convert.ToBase64String(hashedDataBytes); 
     } 
    }//CustomTokenSerializer 
} 

शुभकामनाएं!

2

मैं आपके कोड से गुजर गया और यह सही दिखता है। डब्लूएसई और डब्ल्यूसीएफ साबुन संदेश में बहुत अंतर है लेकिन अंतर केवल इस तरह है कि संदेश पर हस्ताक्षर करने के लिए उपयोग किए जाने वाले प्रमाणपत्र का संदर्भ दिया जाता है।

मुझे लगता है कि यहां मूल मुद्दा प्रमाणपत्रों का गलत उपयोग है। आप दोनों परिवहन और संदेश पारस्परिक सुरक्षा का उपयोग कर रहे हैं। सिद्धांत में इसके लिए चार प्रमाण पत्र की आवश्यकता है। आपको

  • परिवहन सुरक्षा के लिए सेवा प्रमाणपत्र - इस प्रमाणपत्र का उपयोग सर्वर द्वारा एसएसएल कनेक्शन बनाने के लिए किया जाता है। कनेक्शन क्लाइंट को सफलतापूर्वक बनाने के लिए प्रमाण पत्र पर भरोसा करना चाहिए (आपको या तो प्राधिकरण पर भरोसा करने की आवश्यकता है जो प्रमाण पत्र जारी करता है या सर्वर प्रमाण पत्र आपके विश्वसनीय लोगों की दुकान में रखा जाना चाहिए)।
  • परिवहन सुरक्षा के लिए ग्राहक प्रमाण पत्र - इस प्रमाणपत्र का उपयोग परिवहन स्तर पर सर्वर पर क्लाइंट को प्रमाणीकृत करने के लिए किया जाता है - आपके पास अपने व्यक्तिगत स्टोर में प्रमाण पत्र और इसकी निजी कुंजी होनी चाहिए
  • संदेश सुरक्षा के लिए सेवा प्रमाणपत्र - यह प्रमाणपत्र एन्क्रिप्टिंग के लिए उपयोग किया जाता है अनुरोध और हस्ताक्षर प्रतिक्रिया (जब डब्ल्यूएस-सुरक्षा 1.0) का उपयोग किया जाता है। आपको इस मशीन को कहीं भी अपनी मशीन पर रखना होगा (यह आपके ऊपर है कि प्रमाण पत्र लोड करने के लिए किस स्थान का उपयोग किया जाएगा)।
  • संदेश सुरक्षा के लिए क्लाइंट प्रमाणपत्र - इस प्रमाणपत्र का उपयोग एन्क्रिप्ट करने और अनुरोध पर हस्ताक्षर करने के लिए किया जाता है (जब डब्ल्यूएस-सुरक्षा 1.0) का उपयोग किया जाता है। आपको अपनी मशीन पर कहीं भी इस प्रमाणपत्र और इसकी निजी कुंजी की आवश्यकता है (यह आपके ऊपर है कि प्रमाण पत्र लोड करने के लिए किस स्थान का उपयोग किया जाएगा)।

ऐसा लगता है कि आप केवल दो प्रमाणपत्र - एक ग्राहक और एक सर्वर। ऐसे मामले में उन्हें शायद परिवहन और संदेश सुरक्षा दोनों के लिए उपयोग किया जाना चाहिए। लेकिन यहां दिलचस्प मुद्दा आता है - डब्लूएसई उदाहरण में क्लाइंट साइड पर आपका "हस्ताक्षर" प्रमाणपत्र वास्तव में सेवा प्रमाण पत्र है। यदि यह वास्तव में मामला है, तो इसका मतलब है कि क्लाइंट के पास सर्वर की निजी कुंजी तक पहुंच होनी चाहिए - जो कभी नहीं होना चाहिए। यह पीकेआई बुनियादी ढांचे का सबसे बुरा उल्लंघन है। पीकेआई इंफ्रास्ट्रक्चर सर्टिफिकेट अथॉरिटीज पर ट्रस्ट पर आधारित है और निजी चाबियाँ सुरक्षित करने पर आधारित है जहां प्रत्येक प्रतिभागी की अपनी निजी कुंजी किसी और के द्वारा सुलभ नहीं होती है। निजी कुंजी साझा करना सुरक्षा को कम कर देता है। सबसे बुरे मामले में यह किसी भी सुरक्षा के बराबर नहीं हो सकता है क्योंकि निजी कुंजी तक पहुंचने वाला कोई भी व्यक्ति संदेश पर संचार या नकली हस्ताक्षर को रोक सकता है।

यदि मैं सही हूं तो आपको डब्लूएसई 3.0 का उपयोग करना चाहिए और इससे खुश रहना चाहिए। बस डब्ल्यूसीएफ को एचटीटीपीएस के लिए विभिन्न क्लाइंट सर्टिफिकेट का उपयोग करने के लिए मजबूर करना और संदेश सुरक्षा काफी कठिन हो सकती है। आपके पास एकल ClientCertificate संपत्ति है लेकिन आपको HTTPS और संदेश सुरक्षा के लिए अलग-अलग प्रमाणपत्र लोड करने की आवश्यकता है। यह दो गुण और कस्टम SecurityTokenManager के साथ कस्टम ClientCredentials बनाने की आवश्यकता है सही प्रमाणपत्र प्रदाता (वापस जाने के लिए प्रत्येक उपयोग (कि एक सिद्धांत है के लिए लागू करने से -। मैं इसे करने की कोशिश कभी नहीं किया है)

Btw EndpointIdentity साथ आपकी समस्या तथ्य पर आधारित है। कि आपकी सेवा कुछ DNS पर प्रकट हुई है और यदि सेवा प्रमाणपत्र (जो आपके मामले में भी प्रमाण पत्र पर हस्ताक्षर कर रहा है) में विषय अलग है तो आपको अपने एंडपॉइंट के लिए एक नई DNS पहचान बनाना होगा। अन्यथा डब्ल्यूसीएफ प्रमाण पत्र पर भरोसा नहीं करेगा। सर्वर प्रमाणपत्र सर्वर का उपयोग करने के लिए उपयोग किए जाने वाले विषय मिलान DNS नाम के साथ जारी किया जाना चाहिए।

+0

इस Ladislav के साथ आपकी प्रतिक्रिया और सहायता के लिए धन्यवाद। मेरा मुद्दा हल हो गया है। मुझे यकीन नहीं है कि इसका क्या हल हुआ। मैंने नीचे आईबीएम साइट पर पाया और इसे हमारे आईटी गेटवे इंफ्रास्ट्रक्चर समूह के साथ लाया। वे कहते हैं कि डेटापावर को कोई बदलाव नहीं किया गया, लेकिन आज सुबह काम करना शुरू कर दिया !!! मैं एक साथ रखे कस्टम क्रेडेंशियल क्लास के साथ कामकाजी कोड के साथ प्रश्न का उत्तर देने जा रहा हूं। धन्यवाद! – Jawad

+0

आईबीएम: https://publib.boulder.ibm.com/infocenter/ieduasst/v1r1m0/index.jsp?topic=/com.ibm.iea.wdatapower/wdatapower/1.0/xa35/380DataPowerWCFIntegration/player.html जब SSL के साथ BasicHttp बाइंडिंग का उपयोग करके: आप किसी भी ट्रांसपोर्ट बाइंडिंग दावे के लिए सिफर चेक अक्षम करने के लिए अक्षम-एसएसएल-सिफर-चेक पैरामीटर का उपयोग कर सकते हैं। बेसिक ऑथ हैडर वेब सेवा प्रॉक्सी में डिफ़ॉल्ट रूप से समर्थित नहीं है। WWF के साथ इंटर-ऑप करने के लिए WWW-प्रमाणीकरण शीर्षलेख को इंजेक्ट करने के लिए ऑन-त्रुटि नियम की एक कस्टम कॉन्फ़िगरेशन आवश्यक है। – Jawad

संबंधित मुद्दे