ASP.NET Core 3.1中的证书身份验证实现

问题描述 投票:0回答:1

我正在按official docs中的说明在ASP.NET Core证书身份验证中构建一个小功能。

[[注:我不是在构建API,我只是在尝试保护某些控制器的某些Action方法,以便仅当客户端具有客户端证书时才打开这些安全的Action方法。

下图显示我可以保护索引操作现在需要客户端证书的方法。其他动作方法这是“隐私”,不需要客户端证书。结果是该索引操作确实在浏览器中打开(收到403错误),但是在浏览器中打开了隐私操作

enter image description here

完整代码

1。 Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
        webBuilder.ConfigureKestrel(o =>
        {
            o.ConfigureHttpsDefaults(o =>
                o.ClientCertificateMode =
                    ClientCertificateMode.RequireCertificate);
        });
    });

2。 Startup.cs

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
        .AddCertificate(options =>
        {
            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;
                }
            };
        });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseCertificateForwarding();
    app.UseAuthentication();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

3。 MyCertificateValidationService.cs

public class MyCertificateValidationService
{
    public bool ValidateCertificate(X509Certificate2 clientCertificate)
    {
        var cert = new X509Certificate2(Path.Combine("localhost_root_l1.pfx"), "1234");
        if (clientCertificate.Thumbprint == cert.Thumbprint)
        {
            return true;
        }

        return false;
    }
}

4。受保护和不受保护的操作方法

[Authorize]
public IActionResult Index()
{
    return View();
}

public IActionResult Privacy()
{
    return View();
}

[[Note:索引操作方法需要客户端认证,而“隐私”不需要客户端证书。

问题:我遇到的问题是:

  1. CertificateAuthenticationEventsOnAuthenticationFailed位于startup.cs文件的ConfigureServices()方法上,我没有被调用。我通过放置断点检查了它们,但未达到断点。

  2. 也不会调用
  3. MyCertificateValidationService.cs类ValidateCertificate()方法。我也用断点检查过它

请帮助我实施证书授权。

更新

我在C#中以explained in this tutorial创建了2个证书。这些是:

  1. 称为root_localhost.pfx的根证书
  2. 客户端证书称为client.pfx

我用这些证书做了两件事:

a。我将root_localhost.pfx添加到了本地计算机的受信任的根证书颁发机构(在Windows上)(使用CertManager)。

b。我通过chrome浏览器导入了客户端证书。

[接下来,我在VS 2019(控制台)中选择了项目,而不是'IIS Express'并运行了我的项目。我在隐身窗口中打开了网站网址,该网址恰巧是-https://localhost:5001

Chrome要求选择证书,请参见下图:enter image description here

选择它后,我得到了无法访问此网站-ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY,请参见下图:

enter image description here

为什么发生???

c# asp.net asp.net-core asp.net-core-mvc asp.net-core-3.1
1个回答
0
投票

目前您的应用尚未配置为使用客户端证书。原因是您在IIS Express中启动(托管)应用程序。有2个选项:

1]最简单的一种是,切换为在项目模式下运行(该应用程序将在控制台窗口中运行)。您也可以在控制台中手动运行它。

2)稍微复杂一点的方法是将IIS Express配置为与客户端证书一起使用。请按照以下步骤操作:2.1)编辑\ config \ applicationhost.config文件并更改以下部分(更改-拒绝允许)。

      <sectionGroup name="security">
        <section name="access" overrideModeDefault="**Allow**" />
        <section name="applicationDependencies" overrideModeDefault="Deny" />
        <sectionGroup name="authentication">
          <section name="anonymousAuthentication" overrideModeDefault="**Allow**" />

2.2)在您的项目中添加以下文件web.config

<configuration>
    <system.webServer>
        <security>
            <access sslFlags="Ssl,SslNegotiateCert,SslRequireCert" />
          <authentication>
            <anonymousAuthentication enabled="true" />
          </authentication>
        </security>
    </system.webServer>
</configuration>

下一个:

要进行客户端身份验证,必须先获得客户端证书。您可以使用以下命令或任何其他生成客户端证书的方法来创建自签名证书:

#create key
openssl req -newkey rsa:4096 -keyout key.pem -out csr.pem -nodes -days 365 -subj "/CN=Your name"
#create certificate
openssl x509 -req -in csr.pem -signkey key.pem -out cert.pem -days 365
#self sign it
openssl pkcs12 -export -in cert.pem -inkey key.pem -out your_cert.p12

由于此证书是自签名的,因此必须将其添加到本地计算机的可信根证书颁发机构(在Windows上)(使用CertManager)。

之后,您需要使用相同的CertManager将其安装(导入)到您的个人证书存储中,但仅适用于当前用户。替代方法是使用Chrome设置(“管理证书”)。这是Chrome能够将证书发送到服务器所必需的。

还可以在您的应用程序中更改此允许自签名证书的选项。

            services.AddAuthentication(
                    CertificateAuthenticationDefaults.AuthenticationScheme)
                    .AddCertificate(options => 
                    { 
                        **options.AllowedCertificateTypes = CertificateTypes.All**;

在完成所有这些更改之后,您应该在访问网站时要求选择证书。

提示:如果您再次访问同一页面,则在关闭所有Chrome实例之前,可能不会要求您选择要使用的证书。如果您希望它询问选择要使用的证书,请打开一个新的隐身窗口。

© www.soinside.com 2019 - 2024. All rights reserved.