我想使用基于证书的身份验证对连接到在 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/