【问题标题】:Required Client Certificate asp.net core web.api所需的客户端证书 asp.net core web.api
【发布时间】:2023-02-17 16:17:06
【问题描述】:

I want to implement client certificate authentication in my web api. I followed the MSDN documentation and tried other examples on the web. Unfortunately I can't get it to work.

The page can be reached with the certificate mode "noCertificate". But when I implement the following line I get this error.

 opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate;

Here is my code. Maybe someone can spot my mistake. Actually, I would expect the browser to open the certificate selection window.

Programm.cs

using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Security.Cryptography.X509Certificates;
using TestClientCert.Validator;

var builder = WebApplication.CreateBuilder(args);


builder.WebHost.UseKestrel(options =>
{
    options.ConfigureHttpsDefaults(opt =>
    {


        opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate;

    });
});

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();


builder.Services.AddTransient<MyCertificateValidationService>();

builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
    .AddCertificate(options =>
    {
        options.RevocationMode = X509RevocationMode.NoCheck;
        options.AllowedCertificateTypes = CertificateTypes.All;
        options.Events = new CertificateAuthenticationEvents
        {
            OnCertificateValidated = context =>
            {
                var validationService = context.HttpContext.RequestServices.GetService<MyCertificateValidationService>();

                if (validationService.ValidateCertificate(context.ClientCertificate))
                {
                    context.Success();
                }
                else
                {
                    context.Fail("invalid cert");
                }

                return Task.CompletedTask;
            },
            OnAuthenticationFailed = context =>
            {
                context.Fail("invalid cert");
                return Task.CompletedTask;
            }
        };
    });
builder.Services.AddAuthorization();


var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

MyCertificateValidationService.cs

using System.Security.Cryptography.X509Certificates;

namespace TestClientCert.Validator
{
    public class MyCertificateValidationService
    {
        public bool ValidateCertificate(X509Certificate2 clientCertificate)
        {
            string[] allowedThumbprints = { "B30D884E44EC218513CF2A5CA246F0AFA1DD8E9B", "6ECB2E563B9129C72215EE00686CAA95FBC5BEC6" };
            if (allowedThumbprints.Contains(clientCertificate.Thumbprint))
            {
                return true;
            }

            return false;
        }
    }
}

HomeController.cs

using Microsoft.AspNetCore.Mvc;

namespace TestClientCert.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class HomeController : Controller
    {
        [HttpGet]
        public string Get() => "Welcome to Narnia";
    }
}

    标签: c# asp.net-core asp.net-web-api client-certificates mtls


    【解决方案1】:

    我希望浏览器打开证书选择窗口。

    我测试了您的代码,您可能需要使用 PowerShell 命令创建证书并将根 CA 添加到 CertMgr 并在 Chrome 浏览器中添加子证书。

    Step1 使用 PowerShell 命令创建证书

    证书身份验证需要两种类型的证书,它们是:证书颁发机构 (CA) 和子证书。

    1.在PowerShell中创建证书颁发机构(CA)

    首先以管理员身份打开 PowerShell。然后一一运行以下3条命令:

    命令 1:创建自签名证书

    New-SelfSignedCertificate -DnsName "localhost", "localhost" -CertStoreLocation "cert:LocalMachineMy" -NotAfter (Get-Date).AddYears(20) -FriendlyName "Rlocalhost" -KeyUsageProperty All -KeyUsage CertSign, CRLSign, DigitalSignature
    

    此命令将创建自签名证书颁发机构并提供它的thumbprint。请妥善保管此指纹,因为我们将使用它来创建子证书。

    命令 2:设置证书密码(我保留密码 1234。)

    $mypwd = ConvertTo-SecureString -String "1234" -Force -AsPlainText
    

    命令 3:将证书导出到 PFX 文件中

    我们现在将使用我们之前设置的密码,并将其与指纹一起用于将证书导出到 .pfx 文件中。

    运行以下命令,但在此之前使用您之前获得的指纹更改文本"thumbprint"

    Get-ChildItem -Path cert:localMachinemy"thumbprint" | Export-PfxCertificate -FilePath D:
    oot.pfx -Password $mypwd
    

    该命令将在“D”驱动器上导出名为 root.pfx 的证书颁发机构文件。(注意:您也可以使用其他驱动器,例如:C: oot.pfx。)

    2.在PowerShell中创建子证书

    让我们从根 CA 创建子证书。所以运行以下4条命令 逐个。注意:

    在第一个命令中,将 text"ca thumbprint" 更改为您之前获得的根证书的指纹。

    运行第二个命令后,您将获得子证书的指纹。您必须使用此指纹更改第四条命令中的文本"thumbprint"。下面给出了这 4 个命令。

    $rootcert = ( Get-ChildItem -Path cert:LocalMachineMy"ca thumbprint" )
     
    New-SelfSignedCertificate -certstorelocation cert:localmachinemy -dnsname "localhost" -Signer $rootcert -NotAfter (Get-Date).AddYears(20) -FriendlyName "Clocalhost"
     
    $mypwd = ConvertTo-SecureString -String "1234" -Force -AsPlainText
     
    Get-ChildItem -Path cert:localMachinemy"thumbprint" | Export-PfxCertificate -FilePath D:child.pfx -Password $mypwd
    

    名为 child.pfx 的子证书文件将在“D”驱动器上创建。在下图中,我显示了在我的 D 驱动器上创建的两个证书文件。

    Step2 添加根 CA 到 CertMgr

    Windows 使用名为 CertMgr 的实用程序来管理证书。在 Windows 搜索中搜索“CertMgr”或“管理计算机证书”以打开此实用程序。接下来,右键单击“Trusted Root Certification Authorities”下的“Certificates”文件夹,选择All Tasks ➤ Import,然后浏览到D盘上的root.pfx文件。

    单击“下一步”按钮进入下一个屏幕,要求您输入私钥(密码)。回想一下,我们使用“1234”作为密码。继续该过程,您的根 CA 证书将被添加。

    Step3 在 Chrome 浏览器中添加子证书

    现在我们将子证书添加到 chrome 浏览器。因此,转到设置,然后单击“隐私和安全”下的“安全”部分。在这里你会发现现在我们将子证书添加到 chrome 浏览器。因此,转到设置,然后单击“隐私和安全”下的“安全”部分。在这里你会找到Manage device Certificates,点击它打开一个对话窗口。

    在此窗口中,确保您位于“个人”选项卡上,然后单击“导入”按钮。只需导入 child.pfx 文件。和以前一样,在询问时输入密码 1234。

    现在再次在 Visual Studio 上运行你的应用程序并打开 web api 的 url。这次 chrome 会要求您选择子证书。

    结果:

    【讨论】:

      猜你喜欢
      • 2018-05-27
      • 2021-12-12
      • 2021-02-09
      • 2012-10-01
      • 1970-01-01
      • 2016-01-27
      • 2018-07-11
      • 2022-07-11
      • 1970-01-01
      相关资源
      最近更新 更多