IIS是否需要SSL客户端证书而不将其映射到Windows用户?

时间:2015-03-13 19:31:37

标签: asp.net authentication iis ssl client-certificates

我希望能够将SSL客户端证书映射到ASP.NET Identity用户。我希望IIS尽可能多地完成工作(协商客户端证书并可能验证它是否由受信任的CA签名),但我不希望IIS将证书映射到Windows用户。客户端证书将传递到ASP.NET,在那里检查它并映射到ASP.NET Identity用户,该用户将变为ClaimsPrincipal。

到目前为止,我能够让IIS将客户端证书传递到ASP.NET的唯一方法是启用iisClientCertificateMappingAuthentication并设置到Windows帐户的多对一映射(然后从不用于其他任何事情。)有没有办法让IIS在没有这个配置步骤的情况下协商并传递证书?

1 个答案:

答案 0 :(得分:6)

您不必使用iisClientCertificateMappingAuthentication。可以在HttpContext中访问客户端证书。

var clientCert = HttpContext.Request.ClientCertificate;

您可以在整个网站上启用RequireClientCertificate,也可以使用单独的 login-with-clientcertificate 页面。

以下是在ASP.NET MVC中执行此操作的一种方法。希望你可以使用它的一部分来适应你的确切情况。

  1. 首先确保您可以通过启用功能委派来在web.config中设置SslFlags。
  2. IIS - Feature delegation

    1. 使网站接受(但不要求)客户端证书 enter image description here

    2. 设置login-with-clientcertificate-page的路径,其中需要客户端证书。在这种情况下,用户控制器具有CertificateSignin操作。 web.config

    3. 创建登录控制器(伪代码)

      [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
      [AllowAnonymous()]
      public ActionResult CertificateSignIn()
      {
          //Get certificate
          var clientCert = HttpContext.Request.ClientCertificate;
      
          //Validate certificate
          if (!clientCert.IsPresent || !clientCert.IsValid)
          {
              ViewBag.LoginFailedMessage = "The client certificate was not present or did not pass validation";
              return View("Index");
          }
      
          //Call your "custom" ClientCertificate --> User mapping method.
          string userId;
          bool myCertificateMappingParsingResult = Helper.MyCertificateMapping(clientCert, out userId);
      
          if (!myCertificateMappingParsingResult)
          {
              ViewBag.LoginFailedMessage = "Your client certificate did not map correctly";
          }
          else
          {
              //Use custom Membersip provider. Password is not needed!
              if (Membership.ValidateUser(userId, null))
              {
                  //Create authentication ticket
                  FormsAuthentication.SetAuthCookie(userId, false);
                  Response.Redirect("~/");
              }
              else
              {
                  ViewBag.LoginFailedMessage = "Login failed!";
              }
          }
      
          return View("Index");
      }