如何配置IIS / Asp.Net以使用客户端证书进行到服务器的TLS连接

时间:2014-12-23 15:46:41

标签: c# asp.net ssl iis-7 windows-server-2008-r2

我正在研究的网站的一个功能是能够使用客户端证书和TLS将数据发布到远程服务器。

我获得了p12客户端证书,并将其安装/添加到系统中。证书在代码中使用如下,(但只有在安装到系统时似乎才有效):

using (var client = new CertificateWebClient("~/ccert.p12"))
{
   client.UploadFile(endpoint, filepath);
}

public class CertificateWebClient : WebClient
{
    private readonly string _certificateUri;

    public CertificateWebClient(string certificateUri)
    {
        _certificateUri = certificateUri;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        var clientCertificate = new X509Certificate(HostingEnvironment.MapPath(_certificateUri));
        request.ClientCertificates.Add(clientCertificate);
        return request;
    }
}

在本地调试应用程序时,我可以选择允许使用证书:

Request for permission

在服务器上安装证书后,我设法在IIS之外运行一个小型测试程序,它可以在没有任何提示的情况下使用证书。

在IIS中的应用程序池下运行时,我无法弄清楚如何让网站使用该证书。

到目前为止,我发现的一切都是关于添加绑定,以便证书可以用于连接到应用程序的客户端,而不是使用客户端证书连接到其他服务器。

如果它有所不同,这适用于Server 2008 R2上的IIS7。

2 个答案:

答案 0 :(得分:1)

尝试扩展WebClient并将证书添加到WebRequest,如下所示:

   class MyWebClient : WebClient
   {
      protected override WebRequest GetWebRequest(Uri address)
      {
          HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
          request.ClientCertificates.Add(new X509Certificate("~/ccert.p12", "password_if_any_or_empty"));
          return request;
      }
  }

答案 1 :(得分:0)

似乎使用X509Certificate2代替X509Certificate无需身份验证即可运行 - 我认为身份验证是由于证书是从证书存储加载而不是从本地路径加载的。

下面的类允许Asp.Net站点使用文件路径使用自签名客户端证书。

public class CertificateWebClient : WebClient
{
    private readonly string _certificateUri;

    public CertificateWebClient(string certificateUri)
    {
        _certificateUri = certificateUri;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        var clientCertificate = new X509Certificate2(HostingEnvironment.MapPath(_certificateUri), "", X509KeyStorageFlags.MachineKeySet);
        request.ClientCertificates.Add(clientCertificate);
        return request;
    }
}