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

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

我想使用基于证书的身份验证对连接到在 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
Configure :
app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseEndpoints(endpoints =>
{
    // Endpoints
});
Program.cs我已经包括:
webBuilder.ConfigureKestrel(o =>
{
    o.ConfigureHttpsDefaults(o =>
        o.ClientCertificateMode = ClientCertificateMode.RequireCertificate);
});
如果我在浏览器中连接到 API,它会提示我输入证书,但在我选择证书后,OnCertificateValidated也不是 OnAuthenticationFailed事件被触发。经过进一步的测试,我意识到 AddCertificate 中的整个选项配置委托(delegate)来电Startup.cs从不跑。这让我觉得我缺少 Kestrel 的某种配置,但我不知道那是什么。请注意,我的 Web API 不使用 IIS 托管。我还需要做什么才能使用基于自签名证书的身份验证?
到目前为止,我的代码基于此处文档中的说明:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-5.0

最佳答案

好的,所以最后我能够解决我自己的问题。解决它有两个不同的部分,但最终只需要对我的项目代码进行一些小的修改。
识别客户证书
首先,服务器没有将自签名客户端证书识别为有效证书。这可以通过以下任一方式解决: 1. 将所有客户端证书(或签署所有证书的根 CA)添加到操作系统的受信任证书存储区,或 2. 添加 ClientCertificateValidation回调 kestrel 以确定证书是否被接受或拒绝。
#2 的示例(对 ConfigureHttpsDefaults 中的 Program.cs lambda 的调整)如下:

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
        };
    });
});
附带说明,请调用 opts.AllowAnyClientCertificate()是添加 ClientCertificateValidation 的简写始终返回 true 的回调,使所有自签名证书都有效。

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

app.UseRouting();

app.UseAuthentication();

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

app.UseEndpoints(endpoints =>
{
    // Endpoints
});
在此之后,我的 OnCertificateValidated每次连接都会调用事件,我能够执行额外的身份验证逻辑并拒绝无效证书。

关于c# - OnCertificateValidated 未运行 - 自签名证书客户端身份验证 - ASP.NET Core 和 Kestrel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68146868/

相关文章:

c# - 如何在 Math.NET 中从 DenseVector 初始化 Vector<double>?

c# - 将十六进制字符串解析为以 10 为基数的长整数

c# - IFormFile 在 asp.net core 2.1 中总是返回 null

asp.net-mvc - 在模型验证之前获取要执行的过滤器

asp.net-web-api - 如何在 OData 中的 $expand 上跳过、选择、顶部?

asp.net-core - 如何像 JavaScript-SPA 一样托管 ASP.NET API 和 Blazor Web 程序集?

c# - 将值从 C++ 应用程序传递到 C# 应用程序

C# MongoDB 驱动程序——需要简单的代码来读取/查询集合

c# - .net core 应用程序中 ServicePointManager.DefaultConnectionLimit 的最高安全数是多少?

c# - 使用一个连接发送并发 SignalR 消息