如何同时提供用户名和客户端证书在WCF客户端(为什么这个例子中工作)?(How to supply

2019-09-27 08:42发布

考虑一个WCF服务,其中的目的是使在传输层所需的客户端证书(客户端证书设置为“必需的”,在IIS)。 以及,将有在消息层的用户名验证。

现在,我已经看到了这个问题已经:

WCF客户端证书和用户名凭据禁止

我能有所了解发生了什么事情在那里,并认识到固有的WCF不允许两者。 我同样的步骤赴代码按上面的链接海报,发现同样的结果...消息级用户名凭据传递(在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服务。

Answer 1:

以下是我终于实现了它。

服务器配置:

  <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)服务完全通过配置文件,在不改变实际代码。 它仍然允许我向它提交VIA WebRequest的为好,如上图所示。

我必须给予信贷这篇文章:

WCF客户端证书和用户名凭据禁止

还有这样一条:

翻译非的BizTalk WCF配置成的BizTalk WCF的自定义端点

对于终于让我在正确的轨道上。 我总是从自定义绑定退避三舍在WCF,因为我认为这是矫枉过正,但他们真的没有什么疯狂的,只是提供更详细的配置比是现成可用的方式。



文章来源: How to supply both UserName and Client Certificate in WCF client (why does this example work)?
标签: c# wcf soap ssl