gpt4 book ai didi

c# - 如何在 WCF 客户端中同时提供用户名和客户端证书(此示例为何有效)?

转载 作者:太空宇宙 更新时间:2023-11-03 13:12:39 25 4
gpt4 key购买 nike

考虑一个 WCF 服务,其目的是在传输层要求客户端证书(客户端证书在 IIS 中设置为“必需”)。同样,消息层将进行用户名认证。

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

WCF Client Certificate AND UserName Credentials forbidden

我可以稍微理解那里发生了什么,并意识到 WCF 本质上不允许两者。我在代码中执行了与上面引用的链接中的海报相同的步骤,并发现了相同的结果......正在传递消息级用户名凭据(在我的例子中是在 SOAP header 中),但是客户端证书(尽管是在 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 服务。

最佳答案

这是我最终的做法。

服务器配置:

  <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 中的自定义绑定(bind),因为我认为它有点矫枉过正,但它们真的没有什么疯狂的,只是一种提供比开箱即用的更详细配置的方法。

关于c# - 如何在 WCF 客户端中同时提供用户名和客户端证书(此示例为何有效)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21341899/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com