OnCertificateValidated 未运行 - 自签名证书客户端身份验证 - ASP.NET Core 和 Kestrel

The*_*.14 14 c# client-certificates asp.net-web-api asp.net-core

我想使用基于证书的身份验证对连接到在 Kestrel 上运行的 ASP.NET Core Web API (.NET 5) 的客户端进行身份验证。

在我的中,Startup.cs我有以下内容ConfigureServices

services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
    .AddCertificate(options =>
    {
        options.AllowedCertificateTypes = CertificateTypes.All;
        options.Events = new CertificateAuthenticationEvents
        {
            OnCertificateValidated = context =>
            {
                // More code to verify certificates
            },
            OnAuthenticationFailed = context =>
            {
                // More code
            }
        };
    });

// Other services
Run Code Online (Sandbox Code Playgroud)

并在Configure

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseEndpoints(endpoints =>
{
    // Endpoints
});
Run Code Online (Sandbox Code Playgroud)

我在其中Program.cs包括:

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseEndpoints(endpoints =>
{
    // Endpoints
});
Run Code Online (Sandbox Code Playgroud)

如果我在浏览器中连接到 API,它会提示我输入证书,但在我选择证书后,OnCertificateValidatedOnAuthenticationFailed事件都不会触发。AddCertificate经过一些进一步的测试,我意识到调用中的整个选项配置委托Startup.cs永远不会运行。这让我觉得我缺少 Kestrel 的某种配置,但我不知道那是什么。请注意,我的 Web API 不使用 IIS 托管。要使用基于自签名证书的身份验证,我还需要做什么?

到目前为止,我的代码基于此处文档中的说明: https: //learn.microsoft.com/en-us/aspnet/core/security/authentication/certauth ?view=aspnetcore-5.0

The*_*.14 20

好吧,最终我能够解决我自己的问题。解决这个问题需要两个不同的部分,但最终只需要对我的项目代码进行一些小的修改。

识别客户端证书

首先,服务器无法将自签名客户端证书识别为有效证书。这可以通过以下方法解决:1. 将所有客户端证书(或对所有证书进行签名的根 CA)添加到操作系统的受信任证书存储中,或者 2. 添加回调ClientCertificateValidation到 kestrel 以确定证书是否被接受或被拒绝。

ConfigureHttpsDefaults#2 的示例(对中的 lambda进行调整Program.cs)如下:

webBuilder.ConfigureKestrel(o =>
{
    o.ConfigureHttpsDefaults(opts =>
    {
        opts.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
        opts.ClientCertificateValidation = (cert, chain, policyErrors) =>
        {
            // Certificate validation logic here
            // Return true if the certificate is valid or false if it is invalid
        };
    });
});
Run Code Online (Sandbox Code Playgroud)

附带说明一下,调用opts.AllowAnyClientCertificate()是添加始终返回 true 的回调的简写ClientCertificateValidation,使所有自签名证书都有效。


所需授权

应用这两种方法中的任何一种后,我的 API 将接受来自有效证书的查询,但事件中的额外证书验证逻辑OnCertificateValidated仍未运行。这是因为,根据ASP.NET Core 问题 #14033 的评论,除非为正在访问的端点启用授权,否则此事件的额外证书验证将永远不会运行。这是有道理的,因为此事件通常用于根据有关该主题的 ASP.NET Core 文档ClaimsPrincipal从证书生成证书。将 ASP.NET 设置为使用授权并要求对 API 调用进行授权(例如,通过将属性应用于所有控制器)会导致对这些 API 调用运行额外的身份验证检查。[Authorize]

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

// Adding this and adding the [Authorize] attribute
// to controllers fixes the problem.
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    // Endpoints
});
Run Code Online (Sandbox Code Playgroud)

此后,OnCertificateValidated每次连接都会调用我的事件,并且我能够执行额外的身份验证逻辑并拒绝无效证书。

  • 你太棒了,你的帖子对我帮助很大。 (2认同)