通过asp.net中的X509证书进行客户端身份验证

通过asp.net中的X509证书进行客户端身份验证,asp.net,authentication,digital-certificate,Asp.net,Authentication,Digital Certificate,我有一个asp.net应用程序,需要使用X509证书对用户进行身份验证。也就是说,用户必须安装由我颁发的证书,以便他可以浏览我的网站,并且我可以通过该证书确定哪个用户是谁 我已经在IIS上配置了SSL,但这不是我现在想要的,我不知道从哪里开始 如何在asp.net c#中实现这一点?要创建安全的身份验证机制,您需要同时使用客户端证书和用户名/密码。原因是证书是可以被窃取(复制)的东西,而密码是只有个人知道的东西。另一种选择是智能卡上的证书,由PIN保护 要在ASP.NET应用程序中使用客户端证书

我有一个asp.net应用程序,需要使用X509证书对用户进行身份验证。也就是说,用户必须安装由我颁发的证书,以便他可以浏览我的网站,并且我可以通过该证书确定哪个用户是谁

我已经在IIS上配置了SSL,但这不是我现在想要的,我不知道从哪里开始


如何在asp.net c#中实现这一点?

要创建安全的身份验证机制,您需要同时使用客户端证书和用户名/密码。原因是证书是可以被窃取(复制)的东西,而密码是只有个人知道的东西。另一种选择是智能卡上的证书,由PIN保护

要在ASP.NET应用程序中使用客户端证书,您需要执行以下操作:

步骤1:在IIS管理器中,打开应用程序或网站,选择SSL设置,然后选择需要SSL和需要客户端证书

现在,当用户打开您的网站时,浏览器将提示他选择将在通信中使用的客户端证书

重要信息此时,您必须确保证书由您信任的人颁发(因为任何人都可以创建自己的自签名证书)

步骤2:添加配置项(web.config、数据库等)。在此列表中,您将为客户端证书添加整个CA(证书颁发机构)链的指纹

<add key="ClientCertificateIssuerThumbprints" value="4901f5b87d736cd88792bd5ef7caee91bf7d1a2b,0113e31aa85d7fb02740a1257f8bfa534fb8549e,c9321de6b5a82666cf6971a18a56f2d3a8675602"/>

步骤3:创建一个经典用户名/密码登录页面。验证用户名/密码

步骤4:将以下代码添加到登录页面:

var x509 = new X509Certificate2(this.Request.ClientCertificate.Certificate);
var chain = new X509Chain(true);
chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
chain.Build(x509);

var validThumbprints = new HashSet<string>(
    System.Configuration.ConfigurationManager.AppSettings["ClientCertificateIssuerThumbprints"]
        .Replace(" ", "").Split(',', ';'),
    StringComparer.OrdinalIgnoreCase);

// if the certificate is self-signed, verify itself.
for (int i = chain.ChainElements.Count > 1 ? 1 : 0; i < chain.ChainElements.Count; i++)
{
    if (!validThumbprints.Contains(chain.ChainElements[i].Certificate.Thumbprint))
        throw new UnauthorizedAccessException("The client certificate selected is not authorized for this system. Please restart the browser and pick the certificate issued by XXXXX");
}

// certificate Subject would contain some identifier of the user (an ID number, SIN number or anything else unique). here it is assumed that it contains the login name and nothing else
if (!string.Equals("CN=" + login, x509.Subject, StringComparison.OrdinalIgnoreCase))
    throw new UnauthorizedAccessException("The client certificate selected is authorized for another user. Please restart the browser and pick another certificate.");
var x509=新的X509Certificate2(this.Request.ClientCertificate.Certificate);
var链=新X509链(真);
chain.ChainPolicy.RevocationMode=X509RevocationMode.Offline;
链。构建(x509);
var validThumbprints=新哈希集(
System.Configuration.ConfigurationManager.AppSettings[“ClientCertificateIsuerThumbPrints”]
.Replace(“,”).Split(“,”,“;”),
普通木糖酶);
//如果证书是自签名的,请验证自身。
对于(int i=chain.ChainElements.Count>1?1:0;i

只有在同时检查了密码和证书后,才允许用户进入系统。

如果您拥有IIS 7.0或更高版本,则可以配置客户端证书映射身份验证

(非常简单,将映射工作留给AD服务器)


(IIS中需要更多配置,需要访问客户端证书,但可以独立工作,没有到AD的往返)。在这种情况下,您可以指定(一个或多个)用户凭据和

  • 将每个用户映射到您指定其凭据的用户的证书公钥,或
  • 基于证书字段中的值将多个证书映射到用户
配置(多对一):



使用基于客户端证书对客户端进行身份验证的安全令牌服务(STS)。ADFS 2.0可以完善此角色,或者如果此角色不可用,您可以查看。

如果客户端可以导出证书并在任何地方安装,那么证书的意义何在?用户名/密码可确保用户的真实性,但我还需要确保计算机的真实性。可以安装证书,以便无法导出私钥(身份验证所需)。有些笔记本电脑允许您在硬件芯片中安装证书。另一种方法是将证书存储在智能卡中。如果您找到足够的客户端证书,您可以使用它进行身份验证:我同意,我也想对工作站进行身份验证。但我认为我的解决方案是使用一对多客户端证书,并使用元数据生成每个客户端证书来标识工作站(元数据需要加密以获得额外的安全性)。是否可以使用证书对用户进行身份验证,但不提供登录名和密码?用户只需使用带有证书的智能卡,系统将自动登录?AspNet core 2.0有什么新功能吗?我们如何在.net core 2.x中做到这一点?
<location path="Default Web Site">
   <system.webServer>
      <security>
         <access sslFlags="Ssl, SslNegotiateCert" />
          <authentication>
            <windowsAuthentication enabled="false" />
            <anonymousAuthentication enabled="false" />
            <digestAuthentication enabled="false" />
            <basicAuthentication enabled="false" />
            <clientCertificateMappingAuthentication enabled="true" />
         </authentication>
     </security>
   </system.webServer>
</location>
<location path="Default Web Site">
   <system.webServer>
      <security>
         <authentication>
            <windowsAuthentication enabled="false" />
            <anonymousAuthentication enabled="false" />
            <digestAuthentication enabled="false" />
            <basicAuthentication enabled="false" />
            <iisClientCertificateMappingAuthentication enabled="true"
                  manyToOneCertificateMappingsEnabled="true">
               <manyToOneMappings>
                  <add name="Contoso Employees"
                        enabled="true"
                        permissionMode="Allow"
                        userName="Username"
                        password="[enc:AesProvider:57686f6120447564652c2049495320526f636b73:enc]">
                     <rules>
                        <add certificateField="Subject"
                           certificateSubField="O"
                           matchCriteria="Contoso"
                           compareCaseSensitive="true" />
                     </rules>
                  </add>
               </manyToOneMappings>
            </iisClientCertificateMappingAuthentication>
         </authentication>
         <access sslFlags="Ssl, SslNegotiateCert" />
      </security>
   </system.webServer>
</location>