簡體   English   中英

.net核心3.0證書認證

[英].net core 3.0 Certificate authentication

最近,我將 API 從 .net 核心 2.2 遷移到 .net 核心 3.0,以便使用證書實現身份驗證。

我已按照以下 Microsoft 文檔: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.0完成我的工作。 但是我遇到了一個問題:當我調用裝飾有 [Authorize] 屬性的 controller 方法時,從未執行過證書驗證。 如果請求的 header 中沒有證書,我會得到一個 403,這是必需的行為,但如果我放置證書,則假定的行為應該是指紋驗證,但什么都沒有......

這是我的證書驗證服務:

public class CertificateValidationService
{
    public bool ValidateCertificate(X509Certificate2 clientCertificate, string thumbprintToChek) =>
        clientCertificate.Thumbprint.Equals(thumbprintToChek);
}

如文檔中所述,在 StartUp.cs 中,我在ConfigureServices方法中設置了以下代碼行

services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
            .AddCertificate(options => // code from ASP.NET Core sample
            {
                options.AllowedCertificateTypes = CertificateTypes.All;
                options.Events = new CertificateAuthenticationEvents
                {
                    OnCertificateValidated = context =>
                    {
                        var validationService = context.HttpContext.RequestServices.GetService<CertificateValidationService>();

                        if (validationService.ValidateCertificate(context.ClientCertificate, Configuration.GetValue<string>("Apim:CertificateThumbprint")))
                        {
                            var claims = new[]
                            {
                                new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer),
                                new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer)
                            };

                            context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
                            context.Success();
                        }
                        else
                        {
                            context.Fail("Invalid certificate.");
                        }

                        return Task.CompletedTask;
                    }
                };

                options.Events = new CertificateAuthenticationEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        context.Fail("Certificate not valid.");

                        return Task.CompletedTask;
                    }

                };
            });

        services.AddCertificateForwarding(options =>
        {
            options.CertificateHeader = "X-ARR-ClientCert";
            options.HeaderConverter = (headerValue) =>
            {
                X509Certificate2 clientCertificate = null;
                if (!string.IsNullOrWhiteSpace(headerValue))
                {
                    byte[] bytes = headerValue.ToByteArray();
                    clientCertificate = new X509Certificate2(bytes);
                }
                return clientCertificate;
            };
        });

我還使用以下代碼填充了Configure方法:

app.UseCertificateForwarding();
app.UseAuthentication();

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

因此,當我向 API 發出請求時,CertificateForwarding 委托被很好地調用,但 Authentication 委托,從來沒有。

但是,我嘗試在一個全新的項目(僅用於測試)中實現此身份驗證,它運行良好。

您對options.Events的分配完成了兩次。 這樣, OnCertificateValidated的默認實現將覆蓋您的事件處理程序,並且您的CertificateValidationService將永遠不會被調用。

結合這兩個事件處理程序應該得到預期的結果:

options.Events = new CertificateAuthenticationEvents
{
    OnCertificateValidated = context =>
    {
        // Your implementation here.
    },
    OnAuthenticationFailed = context =>
    {
        // Your implementation here.
    }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM