![](/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.