public virtual Task AuthenticationFailed(CertificateAuthenticationFailedContext context) => OnAuthenticationFailed(context);
public static async Task <AuthenticateResult> AuthenticateCertificateAsync( HttpContext context, ILogger logger, CertificateAuthenticationOptions options, CertificateAuthenticationEvents events, AuthenticationScheme scheme) { // You only get client certificates over HTTPS if (!context.Request.IsHttps) { return(AuthenticateResult.NoResult()); } var clientCertificate = await context.Connection.GetClientCertificateAsync(); // This should never be the case, as cert authentication happens long before ASP.NET kicks in. if (clientCertificate == null) { logger.LogDebug("No client certificate found."); return(AuthenticateResult.NoResult()); } // If we have a self signed cert, and they're not allowed, exit early and not bother with // any other validations. if (clientCertificate.IsSelfSigned() && !options.AllowedCertificateTypes.HasFlag(CertificateTypes.SelfSigned)) { logger.LogWarning("Self signed certificate rejected, subject was {0}", clientCertificate.Subject); return(AuthenticateResult.Fail("Options do not allow self signed certificates.")); } // If we have a chained cert, and they're not allowed, exit early and not bother with // any other validations. if (!clientCertificate.IsSelfSigned() && !options.AllowedCertificateTypes.HasFlag(CertificateTypes.Chained)) { logger.LogWarning("Chained certificate rejected, subject was {0}", clientCertificate.Subject); return(AuthenticateResult.Fail("Options do not allow chained certificates.")); } var chainPolicy = BuildChainPolicy(clientCertificate, options); try { var chain = new X509Chain { ChainPolicy = chainPolicy }; var certificateIsValid = chain.Build(clientCertificate); if (!certificateIsValid) { using (logger.BeginScope(clientCertificate.SHA256Thumprint())) { logger.LogWarning("Client certificate failed validation, subject was {0}", clientCertificate.Subject); foreach (var validationFailure in chain.ChainStatus) { logger.LogWarning("{0} {1}", validationFailure.Status, validationFailure.StatusInformation); } } return(AuthenticateResult.Fail("Client certificate failed validation.")); } var validateCertificateContext = new ValidateCertificateContext(context, scheme, options) { ClientCertificate = clientCertificate }; await events.ValidateCertificate(validateCertificateContext); if (validateCertificateContext.Result != null && validateCertificateContext.Result.Succeeded) { return(Success(validateCertificateContext.Principal, clientCertificate, scheme)); } if (validateCertificateContext.Result != null && validateCertificateContext.Result.Failure != null) { return(AuthenticateResult.Fail(validateCertificateContext.Result.Failure)); } var certClaims = clientCertificate.CreateClaimsFromCertificate(options.ClaimsIssuer); return(Success(new ClaimsPrincipal(new ClaimsIdentity(certClaims, CertificateAuthenticationDefaults.AuthenticationScheme)), clientCertificate, scheme)); } catch (Exception ex) { var authenticationFailedContext = new CertificateAuthenticationFailedContext(context, scheme, options) { Exception = ex, }; await events.AuthenticationFailed(authenticationFailedContext); if (authenticationFailedContext.Result != null) { return(authenticationFailedContext.Result); } throw; } }