简体   繁体   English

使用证书身份验证访问Web服务和HTTP接口

[英]Accessing a web service and a HTTP interface using certificate authentication

It is the first time I have to use certificate authentication. 这是我第一次使用证书身份验证。 A commercial partner expose two services, a XML Web Service and a HTTP service. 商业合作伙伴公开两种服务,XML Web服务和HTTP服务。 I have to access both of them with .NET clients. 我必须使用.NET客户端访问它们。

What I have tried 我试过了什么

0. Setting up the environment 0.设置环境

I have installed the SSLCACertificates (on root and two intermediate) and the client certificate in my local machine (win 7 professional) using certmgr.exe. 我已使用certmgr.exe在本地计算机(win 7 professional)中安装了SSLCACertificates(在root和两个中间)和客户端证书。

1. For the web service 1.对于Web服务

  • I have the client certificate (der). 我有客户证书(der)。
  • The service will be consumed via a .NET proxy. 该服务将通过.NET代理使用。

Here's the code: 这是代码:

OrderWSService proxy = new OrderWSService();
string CertFile = "ClientCert_DER.cer";

proxy.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(CertFile));
orderTrackingTO ot = new orderTrackingTO() { order_id = "80", tracking_id = "82", status = stateOrderType.IN_PREPARATION };
resultResponseTO res = proxy.insertOrderTracking(ot);

Exception reported at last statement: The request failed with an empty response . 最后一条语句报告了异常: The request failed with an empty response

2. For the HTTP interface 2.对于HTTP接口

  • it is a HTTPS interface I have to call through POST method. 它是我必须通过POST方法调用的HTTPS接口。
  • The HTTPS request will be send from a .NET client using HTTPWebRequest. HTTPS请求将使用HTTPWebRequest从.NET客户端发送。

Here's the code: 这是代码:

string PostData = "MyPostData";

//setting the request
HttpWebRequest req;
req = (HttpWebRequest)HttpWebRequest.Create(url);
req.UserAgent = "MyUserAgent";
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(CertFile, "MyPassword")); 

//setting the request content
byte[] byteArray = Encoding.UTF8.GetBytes(PostData);
Stream dataStream = req.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

//obtaining the response
WebResponse res = req.GetResponse();
r = new StreamReader(res.GetResponseStream());

Exception reported at last statement: The request was aborted: Could not create SSL/TLS secure channel . 最后一条语句报告的异常: The request was aborted: Could not create SSL/TLS secure channel

3. Last try: using the browser 3.上次尝试:使用浏览器

In Chrome, after installing the certificates, if I try to access both urls I get a 107 error: 在Chrome中,安装证书后,如果我尝试访问这两个网址,则会收到107错误:

Error 107 (net::ERR_SSL_PROTOCOL_ERROR)

I am stuck. 我被卡住了。

The following should help you identify the issue, here are two methods to test SSL connectivity one tests the site whilst the other is a callback method to identify why SSL failed. 以下内容应该可以帮助您确定问题,以下是测试SSL连接的两种方法,一种是测试站点,另一种是回调方法,用于确定SSL失败的原因。 If nothing else it should give you a better idea why it is failing. 如果没有别的东西它应该让你更好地了解它失败的原因。

When the method is called it will pop up with the select certificate dialog box, obviously when you do this for real you'll want to read from the cert store automatically. 当调用该方法时,它将弹出选择证书对话框,显然当您真正执行此操作时,您将希望自动从证书存储区读取。 The reason I have put this in is because if no valid certificate is found then you will know your problem is with the way the certificate is installed. 我之所以这样做是因为如果找不到有效的证书,那么你就会知道你的问题与证书的安装方式有关。

The best thing to do is put this code in a simple console app: 最好的办法是将此代码放在一个简单的控制台应用程序中:

using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Net;

private static void CheckSite(string url, string method)
{
    X509Certificate2 cert = null;
    ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

    X509Store store = new X509Store(StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
    X509Certificate2Collection certcollection = (X509Certificate2Collection)store.Certificates;
    // pick a certificate from the store
    cert = X509Certificate2UI.SelectFromCollection(certcollection, 
            "Caption",
            "Message", X509SelectionFlag.SingleSelection)[0];

    store.Close();

    HttpWebRequest ws = (HttpWebRequest)WebRequest.Create(url);
    ws.Credentials = CredentialCache.DefaultCredentials;
    ws.Method = method;
    if (cert != null)
        ws.ClientCertificates.Add(cert);

    using (HttpWebResponse webResponse = (HttpWebResponse)ws.GetResponse())
    {
        using (Stream responseStream = webResponse.GetResponseStream())
        {
            using (StreamReader responseStreamReader = new StreamReader(responseStream, true))
            {
                string response = responseStreamReader.ReadToEnd();
                Console.WriteLine(response);
                responseStreamReader.Close();
            }

            responseStream.Close();
        }
        webResponse.Close();
    }
}

/// <summary>
/// Certificate validation callback.
/// </summary>
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
    // If the certificate is a valid, signed certificate, return true.
    if (error == System.Net.Security.SslPolicyErrors.None)
    {
        return true;
    }

    Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'",
        cert.Subject,
        error.ToString());

    return false;
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM