【问题标题】:.net core 3.0 Certificate authentication.net core 3.0 证书认证
【发布时间】:2020-03-11 11:09:15
【问题描述】:

最近我将一个 API 从 .net core 2.2 迁移到 .net core 3.0,以便使用证书实现身份验证。

我已遵循此 Microsoft 文档:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.0 来完成我的工作。但我面临一个问题: 当我调用带有 [Authorize] 属性的控制器方法时,从不执行证书验证。如果请求的标头中没有证书,我会得到一个 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 委托被调用,但身份验证委托,永远不会。

但是,我尝试在一个全新的项目(仅用于测试)中实现此身份验证,它运行良好。

【问题讨论】:

  • 好吧,我已经完成了让它工作。我已经删除了我之前添加的所有代码。清理并重建解决方案,然后再次更新 StartUp.cs 和 Program.cs 并且它工作。我不明白第一次出了什么问题,因为代码保持不变。 VS缓存可能有一些问题?

标签: c# authentication x509certificate .net-core-3.0 asp.net-core-3.0


【解决方案1】:

您对options.Events 的分配已完成两次。这样OnCertificateValidated 的默认实现会覆盖您的事件处理程序,您的CertificateValidationService 将永远不会被调用。

结合两个事件处理程序应该会得到预期的结果:

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

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 1970-01-01
    • 2020-04-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多