2014-01-24 113 views
1

考慮一個WCF服務,其中的意圖是在傳輸層需要客戶端證書(客戶端證書在IIS中設置爲「必需」)。同樣,在消息層將會有用戶名認證。如何在WCF客戶端提供用戶名和客戶端證書(爲什麼這個例子工作)?

現在,我已經看到了這個問題已經:

WCF Client Certificate AND UserName Credentials forbidden

,我能有所瞭解發生了什麼事情在那裏,並認識到固有的WCF不允許兩者。我在上面引用的鏈接中通過了代碼中的相同步驟,並找到了相同的結果...消息級UserName憑證正在傳遞(在我的情況下是在SOAP頭中),但客戶證書(儘管存在當在VS調試中查看請求客戶端時附加)實際上未被端點處理。

所以現在出現讓我困惑的部分。我決定稍微修改一下。 我想知道爲什麼這個工程完全像我想要的那樣...它通過IIS客戶端證書要求,用戶名得到傳遞給WCF服務,所有的只是工作。然而WCF不允許我僅僅使用WCF配置文件或代碼(我可以找到)來完成它。爲什麼?

  // sets up a proxy client based on endpoint config 
      // basically just here to get the URL. 
      this.InitializeSubmitClient(); 

      // these get used to create the HttpWebRequest 
      string url = this.submitClient.Endpoint.Address.ToString(); 
      string action = "SubmitCDA"; 

      // this deserializes an XML file which is the "shell" of SOAP document and inject username/password into SOAP Security node 
      XmlDocument soapEnvelopeXml = XMLHelper.CreateSoapDocument(this.txtSubmitCdaXmlFile.Text, this.txtAdAccount.Text, this.txtPassword.Text); 
      HttpWebRequest webRequest = XMLHelper.CreateWebRequest(url, action); 

      // saves the SOAP XML into the webRequest stream. 
      XMLHelper.InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest); 

      // attach the cert 
      if (this.chkSendClientCert.Checked) 
      { 
       X509Certificate myCert = X509Certificate.CreateFromCertFile(@"C:\temp\CDX-IHAT_DevClientCert.cer"); 
       webRequest.ClientCertificates.Add(myCert); 
      } 
      else 
      { 
       webRequest.ClientCertificates.Clear(); 
      } 

      // begin async call to web request. 
      IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null); 

使事情進一步複雜化,適用於此的WCF服務是BizTalk服務。

回答

2

這就是我最終做到的。

服務器配置:

<customBinding> 
    <binding name="CustomCDARequestEndpointBinding">      
     <textMessageEncoding messageVersion="Soap11" /> 
     <security authenticationMode="UserNameOverTransport" /> 
     <httpsTransport requireClientCertificate="true" /> 
    </binding> 
    </customBinding> 

客戶端配置:

<system.ServiceModel> 
    <bindings> 
    <customBindings> 
     <binding name="CustomBinding_ITwoWayAsync"> 
      <security defaultAlgorithmSuite="Default" 
      authenticationMode="UserNameOverTransport" 
      requireDerivedKeys="true" 
      includeTimestamp="true" 
      messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" 
      > 
      <localClientSettings detectReplays="false" /> 
      <localServiceSettings detectReplays="false" /> 
      </security> 
      <textMessageEncoding messageVersion="Soap11" /> 
      <httpsTransport requireClientCertificate="true" /> 
     </binding> 
    </customBinding> 
    </bindings> 
    <behaviors> 
    <endpointBehaviors> 
     <behavior name="ohBehave"> 
     <clientCredentials useIdentityConfiguration="false"> 
     <clientCertificate findValue="6D0DBF387484B25A16D0E3E53DBB178A366DA954" storeLocation="CurrentUser" 
      x509FindType="FindByThumbprint" />    
     </clientCredentials>   
     </behavior> 
    </endpointBehaviors> 
    </behaviors> 
    <client> 
    <endpoint address="https://myservice/CDASubmitService/CDASubmit.svc" 
     binding="customBinding" bindingConfiguration="SubmitDev" behaviorConfiguration="ohBehave" 
     contract="CDASubmitService.CDASubmit" name="SubmitDev" /> 
    </client> 
</system.serviceModel> 

的關鍵,獲得它的工作是<httpsTransport requireClientCertificate="true" />元素和<security authenticationMode="UserNameOverTransport"元素/屬性。

此配置允許我通過配置文件完全向WCF(BizTalk)服務提交消息,而不會更改實際代碼。它仍然允許我提交給威盛WebRequest,如上所示。

我必須給予信貸這個帖子:

WCF Client Certificate AND UserName Credentials forbidden

還有這樣一條:

Translate non-BizTalk WCF config into BizTalk WCF-Custom endpoint

爲終於讓我在正確的軌道上。我總是迴避WCF中的自定義綁定,因爲我認爲這是過度殺傷,但它們確實沒有什麼瘋狂,只是提供比現有可用的更詳細配置的一種方式。