![](/img/trans.png)
[英]How to fix RevocationStatusUnknown in asp.net core 3.1 with self-signed client certificate
[英]OnCertificateValidated not running - Self-Signed Certificate Client Authentication - ASP.NET Core and Kestrel
我想使用基于证书的身份验证对连接到在 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
事件被触发。 经过一些进一步的测试,我意识到Startup.cs
AddCertificate
调用中的整个选项配置委托永远不会运行。 这让我觉得我缺少某种 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 的示例(对Program.cs
的ConfigureHttpsDefaults
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()
是添加始终返回 true 的ClientCertificateValidation
回调的简写,使所有自签名证书都有效。
所需授权
应用这些方法之一后,我的 API 将接受来自有效证书的查询,但我在OnCertificateValidated
事件中的额外证书验证逻辑仍未运行。 这是因为,根据对ASP.NET Core 问题 #14033 的评论,除非为正在访问的端点启用授权,否则此事件的额外证书验证将永远不会运行。 这是有道理的,因为此事件通常用于根据主题上的 ASP.NET Core Docs的证书生成ClaimsPrincipal
。 将 ASP.NET 设置为使用授权并要求对 API 调用进行授权(例如,通过将[Authorize]
属性应用于所有控制器)会导致对这些 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
事件,并且我能够执行额外的身份验证逻辑并拒绝无效证书。
接受的答案对我很有帮助(谢谢!)但它并没有完全解决我的问题。
我发现ClientCertificateValidation
函数不是验证(和拒绝)证书的唯一地方。 使用AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme). AddCertificate...
AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme). AddCertificate...
还导致在处理ClientCertificateValidation
之后触发另一个验证。
为了解决我的问题,我必须在CertificateAuthenticationOptions:
行中配置CustomTrustStore
CertificateAuthenticationOptions:
AddCertificate(options =>
{
options.AllowedCertificateTypes = CertificateTypes.All;
options.ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust;
options.CustomTrustStore = new X509Certificate2Collection { rootCert };
options.RevocationMode = X509RevocationMode.NoCheck;
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
if (validationService.ValidateCertificate(context.ClientCertificate))
{
context.Success();
}
else
{
context.Fail("invalid cert");
}
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
context.Fail("invalid cert");
return Task.CompletedTask;
}
};
});
rootCert
是通过以下方式启动的:
var rootCert = new X509Certificate2("RootCert.pfx", "1234");
并且RootCert.pfx
作为文件添加到项目中。
由于我们现在使用AddAuthentication(.).AddCertificate
的内置验证,我们应该使用AllowAnyCertificate()
禁用较早的验证(此验证不知道我们的自定义根信任):
builder.WebHost.ConfigureKestrel(kso =>
{
kso.ConfigureHttpsDefaults(cao => {
cao.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
cao.AllowAnyClientCertificate();
cao.CheckCertificateRevocation = false;
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.