首页 > 解决方案 > 证书身份验证 403 访问被拒绝

问题描述

我们创建了需要客户端证书进行身份验证的服务。服务器获取证书,验证并生成 JWT 令牌。技术是.net 的核心
问题是当客户按下证书选择上的取消按钮时,下一次当他尝试时,他得到 403 access denied 并且证书选择没有出现。我在互联网上发现了一些可以正常工作的服务。在每个请求证书选择窗口出现。但是他们的服务是用不同的技术编写的(java : server APACHE)。

代码在这里: Program.cs

public static IHostBuilder CreateHostBuilder(string[] args)
        {
            BuildConfiguration();

            XmlConfigurator.Configure(LogManager.GetRepository(Assembly.GetEntryAssembly()), new FileInfo("log4net.config"));

            X509Certificate2 certificate = GetServiceCertificate(Configuration.GetSection("AppSetting")["SSlCertname"], Configuration.GetSection("AppSetting")["SSLCertPassw"]);
            IHostBuilder whb = Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.ConfigureKestrel(o =>
                {
                    o.ConfigureHttpsDefaults(o =>
                o.ClientCertificateMode =
                    ClientCertificateMode.RequireCertificate);
                });

                webBuilder.UseKestrel(options =>
                {
                    options.Listen(new IPEndPoint(IPAddress.Any, Convert.ToInt32(Configuration.GetSection("AppSetting")["PortNumber"])), listenOptions =>
                    {
                        var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions()
                        {
                            ClientCertificateMode = ClientCertificateMode.AllowCertificate,
                            SslProtocols = System.Security.Authentication.SslProtocols.Tls12,
                            ServerCertificate = certificate
                            //,
                            //ServerCertificateSelector= (connectionContext, name) =>
                            //{
                            //    return null ;
                            //}
                        };
                        listenOptions.UseHttps(httpsConnectionAdapterOptions);
                        listenOptions.Protocols = HttpProtocols.Http1;
                    });
                });
            });

            return whb;
        }

 public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();

启动.cs

public class Startup
    {

        public IConfiguration Configuration { get; }

        protected readonly ILog _logger;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        }

        public void ConfigureServices(IServiceCollection services)
        {

            services.InstallServicesAssembly(Configuration);
            services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
            .AddCertificate(options =>
           {
               options.AllowedCertificateTypes = CertificateTypes.Chained;
               options.RevocationFlag = System.Security.Cryptography.X509Certificates.X509RevocationFlag.EntireChain;
               options.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
               options.Events = new CertificateAuthenticationEvents
               {
                   OnCertificateValidated = async (context) =>
                   {
                       _logger.Info($"/n--------Certificate Validation Process start --------/n");

                       if (context.ClientCertificate == null)
                       {
                           context.Success();
                            //context.Fail("Certificate is null");
                            return;
                       }
                       Console.WriteLine("Validation Start");

                       ContainerResult<ValidateCertificateOutput> data = await context.HttpContext.RequestServices
                       .GetService<ICertificateValidationService>().ValidateCertificate(new ValidateCertificateInput
                       {
                           LoginCertificate = context.ClientCertificate
                       });

                       if (!data.IsSuccess)
                       {
                           context.Fail(data.ErrorList[0].ErrorMessage);
                           _logger.Error($"{data.ErrorList[0].ErrorMessage}");
                           return;
                       }
                       context.Principal = new ClaimsPrincipal(new ClaimsIdentity(data.Output.CertificateClaims, context.Scheme.Name));

                       _logger.Info($"Success Data : {data.Output.CertificateClaims[0].Value}");
                       _logger.Info($"/n--------Certificate Validation Process End --------/n");
                       context.Success();

                   },
                   OnAuthenticationFailed = async (context) =>
                   {

                   }


               };
           });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCertificateForwarding();
            app.UseAuthentication();
            app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
            app.UseAuthorization();
            app.UseEndpoints(endpoints => endpoints.MapControllers());
        }
    }

笔记:

为了解决第二次尝试问题,我们需要关闭浏览器并再次打开。

有关此问题的更多信息,请通过将我的服务与互联网上的其他服务进行比较来进行一些研究。

这就是结果。
我的服务

1. 卷曲详细响应:

 curl --insecure -v https://myservice.com:4530/api/v1/certificate/login?origin=http://test.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying [*.*.*.*]:4530...
* Connected to myservice.com ([*.*.*.*]) port 4530 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: D:/Dev/Git/Git/mingw64/ssl/certs/ca-bundle.crt
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [100 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [4571 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
{ [30 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
} [7 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=*.myservice.com
*  start date: Apr 13 00:00:00 2020 GMT
*  expire date: May  9 23:59:59 2022 GMT
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
*  SSL certificate verify ok.
} [5 bytes data]
> GET /api/v1/certificate/login?origin=http://test.com HTTP/1.1
> Host: myservice.com:4530
> User-Agent: curl/7.69.1
> Accept: */*
>
{ [5 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Date: Wed, 17 Mar 2021 11:32:03 GMT
< Server: Kestrel
< Content-Length: 0
< Strict-Transport-Security: max-age=2592000
<
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Connection #0 to host myservice.com left intact

2. 其他工作服务

$ curl --insecure -v https://otherservice.com:5543/digital-login/digital-login
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying [*.*.*.*]:5543...
* Connected to otherservice.com ([*.*.*.*]) port 5543 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: D:/Dev/Git/Git/mingw64/ssl/certs/ca-bundle.crt
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [97 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [5529 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
{ [362 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
} [7 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS alert, handshake failure (552):
{ [2 bytes data]
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

标签: c#authenticationssl.net-coreclient-certificates

解决方案


推荐阅读