简体   繁体   English

HttpContext.RequestServices.GetService<>() 返回的证书验证服务为 null

[英]Certificate Validation Service returned by HttpContext.RequestServices.GetService<>() is null

I am attempting to follow Microsoft Documentation and other blogs that demonstrate Certificate Authentication in ASP.NET Core.我正在尝试关注在 ASP.NET 核心中演示证书身份验证的Microsoft 文档和其他博客 The call RequestServices.GetService() is returning null.调用 RequestServices.GetService() 将返回 null。 I added the null check on the validationService variable for a sanity check that it was the null reference.我在 validationService 变量上添加了 null 检查,以检查它是 null 参考。

public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate(options =>
        {
            options.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
            options.Events = new CertificateAuthenticationEvents
            {
                OnCertificateValidated = context =>
                {
                    var validationService = context.HttpContext.RequestServices.GetService<MyCertificateValidationService>();

                    if (validationService == null)
                    {
                        throw new NullReferenceException("Validation Service returned by GetService<MyCertificateValidationService>() is null");
                    }

                    if (validationService.ValidateCertificate(context?.ClientCertificate))
                    {
                        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();
                    }

                    return Task.CompletedTask;
                }
            };
        });

        services.AddControllers();

        services.AddMvc()
            .AddXmlSerializerFormatters();
    }

The validation service class:验证服务 class:

public class MyCertificateValidationService
{
    public bool ValidateCertificate(X509Certificate2 clientCertificate)
    {
        bool valid = false;

        var cert = new X509Certificate2(Path.Combine("Test.crt"), ")F@4R9df3s75(5g0");

        if (clientCertificate.Thumbprint == cert.Thumbprint)
        {
            valid = true;
        }

        return valid;
    }
}

Here is the Configure method in Startup:下面是 Startup 中的 Configure 方法:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseCertificateForwarding();
        app.UseAuthentication();

        loggerFactory.AddSerilog();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/error");
        }

        app.UseMiddleware<SerilogMiddleware>();

        app.UseMiddleware<AuthenticationMiddleware>();
        
        app.UseRouting();

        app.UseEndpoints(endPoints =>
        {
            endPoints.MapControllers();
        });
    }

As king king says, if you want to use custom certificate handler service, you should register it firstly and then use it like below:正如 king king 所说,如果你想使用自定义证书处理服务,你应该先注册它,然后像下面这样使用它:

Notice: The document has mentioned that you could also used ICertificateValidationService , you also need to build this service by yourself and register it as service, if you want to get it from context.HttpContext.RequestServices.GetService method.注意:文档中提到您也可以使用ICertificateValidationService ,如果您想从context.HttpContext.RequestServices.GetService方法中获取它,您还需要自己构建该服务并将其注册为服务。

public void ConfigureServices(IServiceCollection services)
    {
         services.AddSingleton<MyCertificateValidationService>();
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate(options =>
                {
                    options.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
                    options.Events = new CertificateAuthenticationEvents
                    {
                        OnCertificateValidated = context =>
                        {
                            var validationService = context.HttpContext.RequestServices.GetService<MyCertificateValidationService>();
        
                            if (validationService == null)
                            {
                                throw new NullReferenceException("Validation Service returned by GetService<MyCertificateValidationService>() is null");
                            }
        
                            if (validationService.ValidateCertificate(context?.ClientCertificate))
                            {
                                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();
                            }
        
                            return Task.CompletedTask;
                        }
                    };
                });
        
                services.AddControllers();
        
                services.AddMvc()
                    .AddXmlSerializerFormatters();
            }

Also I suggest you could refer to this github demo to know how it works with client certificate auth.另外我建议您可以参考此github 演示以了解它如何与客户端证书身份验证一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在派生 controller 中模拟 HttpContext.RequestServices.GetService<> 注入的服务? - How to mock service injected by HttpContext.RequestServices.GetService<> in derived controller? HttpContext.RequestServices.GetService<T> () 与 services.AddScope<T> ()? - HttpContext.RequestServices.GetService<T>() vs services.AddScope<T>()? context.RequestServices.GetService()解析为null - context.RequestServices.GetService() resolving null WCF服务中的HttpContext为null? - HttpContext null in WCF service? ActionFilterAttribute 中的 GetService 返回 null - GetService in ActionFilterAttribute returns null 由于 serviceProvider.GetService,无法添加 singleton 服务<irabbitmqconsumer> () 返回 null</irabbitmqconsumer> - Unable to add a singleton service due to serviceProvider.GetService<IRabbitMQConsumer>() returning null 在Windows Service托管的WCF数据服务中,HttpContext.Current为null - HttpContext.Current is null in WCF Data Service hosted in Windows Service 当用于事件时,是否可以避免为 DI 需求调用 `HttpContext.RequestServices`? - Is it possible to avoid calling `HttpContext.RequestServices` for DI needs when used for events? 调用GetService后,WF DesignerView为null - WF DesignerView is null after GetService is invoked 使用 IOptionsMonitor 获取服务<settings>返回 null object</settings> - GetService with IOptionsMonitor<Settings> returns null object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM