建立 TLS 连接时忽略分配的客户端证书
Assigned client certificate is ignored when TLS connection established
在这个问题中 Connecting to a Web Service using Client Certificate authentication 我正在尝试使用服务器管理员提供的客户端证书从 c# 调用 SOAP Web 服务。就像那个问题一样,我可以在浏览器中使用提供的证书访问 Web 服务(他使用 CURL,我可以使用 IE 但不能使用 FF)。我已经确定在浏览器和下面的代码中使用了相同的证书,并且服务器支持 TLS 1.2 与链接问题不同 - 这是唯一让我的问题不同的东西。
证书已导入 My
和 Root
商店,我可以确定在调用 WS 方法之前已找到它并将其分配给 WS 对象实例。
但是在跟踪中我可以看到它被忽略了:
System.Net Information: 0 : [5928]
TlsStream#11958757::.ctor(host=wsuat.domain.com, #certs=0)
我使用的代码非常简单,我从以前的开发人员那里继承了它,并在大约 1 年前被告知它 "used to work"。注释掉证书分配行后,它在本地工作正常,但是一旦我尝试在打开双向 SSL 的情况下访问服务器上的 WS,它就会失败:
using (ASoapClient client = new ASoapClient())
{
try
{
//ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine
,StoreName.Root // also can load from .My
,X509FindType.FindBySerialNumber // also can find by SubjectName
,"FA33.........................634"
);
SubmitResult rr = client.Submit(req);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error submitting");
}
}
当我将 Expect100Continue
设置为 true
时,出现以下异常:
System.ServiceModel.CommunicationException: An error occurred while making the HTTP request to https://wsuat.domain.com/wsuat/ws.asmx.
This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.
---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
当我评论出来时,我得到以下信息:
System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'wsuat.domain.com'.
---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
正如经常发生的那样,当我绝望地问这个问题时,答案就找到了。在 MSDN 中查找了 basicHttpBinding
安全模式,发现提到了传输 clientCredentialType
属性。
添加 transport
元素并将其设置为 Certificate
后,一切正常:
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
在这个问题中 Connecting to a Web Service using Client Certificate authentication 我正在尝试使用服务器管理员提供的客户端证书从 c# 调用 SOAP Web 服务。就像那个问题一样,我可以在浏览器中使用提供的证书访问 Web 服务(他使用 CURL,我可以使用 IE 但不能使用 FF)。我已经确定在浏览器和下面的代码中使用了相同的证书,并且服务器支持 TLS 1.2 与链接问题不同 - 这是唯一让我的问题不同的东西。
证书已导入 My
和 Root
商店,我可以确定在调用 WS 方法之前已找到它并将其分配给 WS 对象实例。
但是在跟踪中我可以看到它被忽略了:
System.Net Information: 0 : [5928] TlsStream#11958757::.ctor(host=wsuat.domain.com, #certs=0)
我使用的代码非常简单,我从以前的开发人员那里继承了它,并在大约 1 年前被告知它 "used to work"。注释掉证书分配行后,它在本地工作正常,但是一旦我尝试在打开双向 SSL 的情况下访问服务器上的 WS,它就会失败:
using (ASoapClient client = new ASoapClient())
{
try
{
//ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine
,StoreName.Root // also can load from .My
,X509FindType.FindBySerialNumber // also can find by SubjectName
,"FA33.........................634"
);
SubmitResult rr = client.Submit(req);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error submitting");
}
}
当我将 Expect100Continue
设置为 true
时,出现以下异常:
System.ServiceModel.CommunicationException: An error occurred while making the HTTP request to https://wsuat.domain.com/wsuat/ws.asmx.
This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.
---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
当我评论出来时,我得到以下信息:
System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'wsuat.domain.com'.
---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
正如经常发生的那样,当我绝望地问这个问题时,答案就找到了。在 MSDN 中查找了 basicHttpBinding
安全模式,发现提到了传输 clientCredentialType
属性。
添加 transport
元素并将其设置为 Certificate
后,一切正常:
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>