简体   繁体   English

如何在WCF客户端中提供UserName和Client Certificate(为什么这个例子有用)?

[英]How to supply both UserName and Client Certificate in WCF client (why does this example work)?

Consider a WCF service in which the intent is to have Client Certificates required at the Transport layer (Client Certificates set to "Required" in IIS). 考虑一个WCF服务,其目的是在传输层需要客户端证书(IIS中的客户端证书设置为“必需”)。 As well, there will be username authentication at the message layer. 同样,消息层将有用户名验证。

Now I've seen this question already: 现在我已经看到了这个问题:

WCF Client Certificate AND UserName Credentials forbidden WCF客户端证书和用户名凭据被禁止

and I can somewhat understand what's going on there and realize that inherently WCF does not allow both. 我可以在某种程度上理解那里发生了什么,并意识到WCF本身并不允许这两者。 I went through the same steps in code as the poster in the link referenced above and found the same result...the message-level UserName credentials were being passed (in the SOAP header in my case), but the Client Cert (despite being attached when the request client is viewed in VS debug) was not actually being processed by the endpoint. 我在代码中执行了与上面引用的链接中的海报相同的步骤,并找到了相同的结果...消息级别的UserName凭据被传递(在我的情况下在SOAP标头中),但客户端证书(尽管是在VS调试中查看请求客户端时附加的)实际上并未由端点处理。

So now comes the part that has me confused. 所以现在让我困惑的那部分。 I decided to hack it somewhat. 我决定稍微破解它。 I'm wondering why this works exactly like I'm wanting...it gets past IIS Client Cert requirement, the UserName gets passed to the WCF Service and all just works. 我想知道为什么这个工作完全像我想要的...它超过了IIS客户端证书要求,UserName被传递给WCF服务,一切正常。 Yet WCF does not allow me to do it just using WCF config files or code (that I can find). 然而,WCF不允许我只使用WCF配置文件或代码(我能找到)。 Why? 为什么?

            // 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);

To further complicate matters, the WCF Service that this applies to is a BizTalk service. 更复杂的是,适用的WCF服务是BizTalk服务。

Here's how I ended up doing it. 这是我最终如何做到这一点。

The Server Config: 服务器配置:

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

The Client Config: 客户端配置:

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

The key to getting it working was the <httpsTransport requireClientCertificate="true" /> element and the <security authenticationMode="UserNameOverTransport" element/attribute. 使其正常工作的关键是<httpsTransport requireClientCertificate="true" />元素和<security authenticationMode="UserNameOverTransport"元素/属性。

This configuration allowed me to submit a message to a WCF (BizTalk) service completely through configuration files, with no changes to actual code. 此配置允许我完全通过配置文件向WCF(BizTalk)服务提交消息,而不更改实际代码。 It still allows me to submit to it VIA WebRequest as well, as shown above. 它仍允许我提交VIA WebRequest,如上所示。

I have to give credit to this post: 我要赞扬这篇文章:

WCF Client Certificate AND UserName Credentials forbidden WCF客户端证书和用户名凭据被禁止

as well as this one: 以及这一个:

Translate non-BizTalk WCF config into BizTalk WCF-Custom endpoint 将非BizTalk WCF配置转换为BizTalk WCF-Custom端点

for finally getting me on the right track. 最终让我走上了正确的轨道。 I always shied away from Custom Bindings in WCF because I assumed it was overkill, but they are really nothing crazy, just a way to supply more detailed config than is available out of the box. 我总是回避WCF中的自定义绑定,因为我认为它有点矫枉过正,但它们真的没什么了不起的,只是一种提供比开箱即用更详细的配置的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 客户端在WCF中是否需要用于用户名身份验证的证书 - Does the client need a certificate for username authentication in WCF 带有用户名令牌和客户端证书的WCF SOAP调用 - WCF SOAP call with both username token and client certificate 如何配置 wcf 服务客户端以在消息级别同时使用证书和用户名凭据? - How to configure a wcf service client to use both certificate and username credentials at the message level? 具有基本证书验证和客户端证书验证的WCF客户端 - WCF Client with both Basic and Client Certificate Authentication WCF 客户端证书和用户名凭据被禁止 - WCF Client Certificate AND UserName Credentials forbidden 结合使用Certificate和UserName在WCF中通过basicHttpsBinding进行客户端身份验证以传递反向代理身份验证 - Use both Certificate and UserName for client authentication in WCF with basicHttpsBinding for passing reverse proxy authentication 如何在WCF中吊销客户端证书? - How to revoke a client certificate in WCF? WCF和客户端证书身份验证 - WCF and client certificate authentication 如何配置WCF以将HTTP与客户端证书一起使用? - How to configure WCF to use HTTP with Client Certificate? 如何将检查器放在客户端和服务器WCF上 - how to put inspector on both client and server WCF
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM