带有客户端证书的 HttpWebRequest 总是收到错误 "The request was aborted: Could not create SSL/TLS secure channel."
HttpWebRequest with client certificate always getting the error "The request was aborted: Could not create SSL/TLS secure channel."
我正在使用 C# HttpWebRequest 向通过客户端证书进行身份验证的 Web 服务发送 XML 请求(该证书已由 public 机构提供,并且有效且已正确安装在服务器中证书存储)。
这是我的代码:
public void CallWebService()
{
var _url = webServiceUrl;
var _action = "soapActionToCall";
X509Certificate2 Cert = null;
try
{
//Search for the certificate in the store
X509Store Store = new X509Store(StoreName.Root);
Store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection Coll = Store.Certificates.Find(X509FindType.FindBySubjectName, "certifcateCommonName", false);
if (Coll != null && Coll.Count > 0)
{
Cert = Coll[0];
}
else
throw new Exception("Certificate non found!");
//Method to create the soap XML envelope
XmlDocument soapEnvelopeXml = CreateSoapEnvelope(typeOfService);
HttpWebRequest webRequest = CreateWebRequest(_url, _action, soapEnvelopeXml.InnerText.Length);
webRequest.ClientCertificates.Add(Cert);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
//Display the XML result
txtResponse.Text = soapResult;
}
}
catch (WebException webEx)
{
WebResponse errResp = webEx.Response;
string text = "";
XmlDocument xmlRsp = null;
string error = "";
if (errResp != null)
{
using (Stream respStream = errResp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream);
text = reader.ReadToEnd();
}
xmlRsp = new XmlDocument();
xmlRsp.LoadXml(text);
if (xmlRsp.GetElementsByTagName("soapenv:Fault").Count > 0)
error = xmlRsp.SelectSingleNode("//error").InnerText;
if (error.Length > 0)
throw new Exception(error);
else
throw webEx;
}
else
throw webEx;
}
}
private HttpWebRequest CreateWebRequest(string url, string action, int contentLength)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.Host = "host";
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.ContentLength = contentLength;
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
ServicePointManager.Expect100Continue = true;
// { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } }.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
// allows for validation of SSL conversations
ServicePointManager.ServerCertificateValidationCallback = delegate(
Object obj, X509Certificate certificate, X509Chain chain,
SslPolicyErrors errors)
{
return (true);
};
return webRequest;
}
private XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelop = new XmlDocument();
soapEnvelop.Load("XmlFileToSend.xml");
return soapEnvelop;
}
private void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
当代码在 webRequest.GetRequestStream() 行输入方法 InsertSoapEnvelopeIntoWebRequest 时,我总是检索错误 "The request was aborted: Could not create SSL/TLS secure channel."。
有人有想法帮助我吗?
我刚刚解决了一个非常相似的问题。在我的例子中,只要我们将客户端证书附加到 WebRequestHandler,我们就会收到 "The request was aborted: Could not create SSL/TLS secure channel." 错误。
在这种情况下,解决方案是授予 IIS_IUSRS 用户组读取客户端证书私钥的权限。一旦完成,错误就消失了。
您可以在 mmc 的证书管理单元中执行此操作。在适当的商店中找到客户端证书,右键单击它 -> 所有任务 -> 管理私钥 -> 添加执行您进程的用户或用户组(如果您在 IIS 上 运行,则 IIS_IUSRS 有效) 并确保它具有 "Read" 权限。
我正在使用 C# HttpWebRequest 向通过客户端证书进行身份验证的 Web 服务发送 XML 请求(该证书已由 public 机构提供,并且有效且已正确安装在服务器中证书存储)。
这是我的代码:
public void CallWebService()
{
var _url = webServiceUrl;
var _action = "soapActionToCall";
X509Certificate2 Cert = null;
try
{
//Search for the certificate in the store
X509Store Store = new X509Store(StoreName.Root);
Store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection Coll = Store.Certificates.Find(X509FindType.FindBySubjectName, "certifcateCommonName", false);
if (Coll != null && Coll.Count > 0)
{
Cert = Coll[0];
}
else
throw new Exception("Certificate non found!");
//Method to create the soap XML envelope
XmlDocument soapEnvelopeXml = CreateSoapEnvelope(typeOfService);
HttpWebRequest webRequest = CreateWebRequest(_url, _action, soapEnvelopeXml.InnerText.Length);
webRequest.ClientCertificates.Add(Cert);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
//Display the XML result
txtResponse.Text = soapResult;
}
}
catch (WebException webEx)
{
WebResponse errResp = webEx.Response;
string text = "";
XmlDocument xmlRsp = null;
string error = "";
if (errResp != null)
{
using (Stream respStream = errResp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream);
text = reader.ReadToEnd();
}
xmlRsp = new XmlDocument();
xmlRsp.LoadXml(text);
if (xmlRsp.GetElementsByTagName("soapenv:Fault").Count > 0)
error = xmlRsp.SelectSingleNode("//error").InnerText;
if (error.Length > 0)
throw new Exception(error);
else
throw webEx;
}
else
throw webEx;
}
}
private HttpWebRequest CreateWebRequest(string url, string action, int contentLength)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.Host = "host";
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.ContentLength = contentLength;
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
ServicePointManager.Expect100Continue = true;
// { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } }.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
// allows for validation of SSL conversations
ServicePointManager.ServerCertificateValidationCallback = delegate(
Object obj, X509Certificate certificate, X509Chain chain,
SslPolicyErrors errors)
{
return (true);
};
return webRequest;
}
private XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelop = new XmlDocument();
soapEnvelop.Load("XmlFileToSend.xml");
return soapEnvelop;
}
private void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
当代码在 webRequest.GetRequestStream() 行输入方法 InsertSoapEnvelopeIntoWebRequest 时,我总是检索错误 "The request was aborted: Could not create SSL/TLS secure channel."。 有人有想法帮助我吗?
我刚刚解决了一个非常相似的问题。在我的例子中,只要我们将客户端证书附加到 WebRequestHandler,我们就会收到 "The request was aborted: Could not create SSL/TLS secure channel." 错误。
在这种情况下,解决方案是授予 IIS_IUSRS 用户组读取客户端证书私钥的权限。一旦完成,错误就消失了。
您可以在 mmc 的证书管理单元中执行此操作。在适当的商店中找到客户端证书,右键单击它 -> 所有任务 -> 管理私钥 -> 添加执行您进程的用户或用户组(如果您在 IIS 上 运行,则 IIS_IUSRS 有效) 并确保它具有 "Read" 权限。