コード例 #1
0
            internal bool TryValidate(X509Certificate2 certificate, out Exception exception)
            {
                using (X509Chain chain = new X509Chain(this.useMachineContext))
                {
                    chain.ChainPolicy = this.chainPolicy;

                    if (!chain.Build(certificate))
                    {
                        exception = new SecurityTokenValidationException(SR.GetString(SR.X509ChainBuildFail,
                                                                                      SecurityUtils.GetCertificateId(certificate), GetChainStatusInformation(chain.ChainStatus)));
                        return(false);
                    }

                    if (chain.ChainElements.Count > 1)  //is not self-signed
                    {
                        chain.ChainPolicy = OidChainPolicy;

                        X509Certificate2 cert = chain.ChainElements[1].Certificate;

                        if (!chain.Build(cert))
                        {
                            exception = new SecurityTokenValidationException(SR.GetString(SR.X509ChainBuildFail,
                                                                                          SecurityUtils.GetCertificateId(certificate), GetChainStatusInformation(chain.ChainStatus)));
                            return(false);
                        }
                    }

                    exception = null;
                    return(true);
                }
            }
コード例 #2
0
            internal bool TryValidate(X509Certificate2 certificate, out Exception exception)
            {
                // Checklist
                // 1) time validity of cert
                // 2) in trusted people store
                // 3) not in disallowed store

                // The following code could be written as:
                // DateTime now = DateTime.UtcNow;
                // if (now > certificate.NotAfter.ToUniversalTime() || now < certificate.NotBefore.ToUniversalTime())
                //
                // this is because X509Certificate2.xxx doesn't return UT.  However this would be a SMALL perf hit.
                // I put a DebugAssert so that this will ensure that the we are compatible with the CLR we shipped with

                DateTime now = DateTime.Now;

                DiagnosticUtility.DebugAssert(now.Kind == certificate.NotAfter.Kind && now.Kind == certificate.NotBefore.Kind, "");

                if (now > certificate.NotAfter || now < certificate.NotBefore)
                {
                    exception = new SecurityTokenValidationException(SR.Format(SR.X509InvalidUsageTime,
                                                                               SecurityUtils.GetCertificateId(certificate), now, certificate.NotBefore, certificate.NotAfter));
                    return(false);
                }

                if (!StoreContainsCertificate(StoreName.TrustedPeople, certificate))
                {
                    exception = new SecurityTokenValidationException(SR.Format(SR.X509IsNotInTrustedStore,
                                                                               SecurityUtils.GetCertificateId(certificate)));
                    return(false);
                }

                if (StoreContainsCertificate(StoreName.Disallowed, certificate))
                {
                    exception = new SecurityTokenValidationException(SR.Format(SR.X509IsInUntrustedStore,
                                                                               SecurityUtils.GetCertificateId(certificate)));
                    return(false);
                }
                exception = null;
                return(true);
            }
コード例 #3
0
            internal bool TryValidate(X509Certificate2 certificate, out Exception exception)
            {
                DateTime now = DateTime.Now;

                if ((now > certificate.NotAfter) || (now < certificate.NotBefore))
                {
                    exception = new SecurityTokenValidationException(System.IdentityModel.SR.GetString("X509InvalidUsageTime", new object[] { System.IdentityModel.SecurityUtils.GetCertificateId(certificate), now, certificate.NotBefore, certificate.NotAfter }));
                    return(false);
                }
                if (!StoreContainsCertificate(StoreName.TrustedPeople, certificate))
                {
                    exception = new SecurityTokenValidationException(System.IdentityModel.SR.GetString("X509IsNotInTrustedStore", new object[] { System.IdentityModel.SecurityUtils.GetCertificateId(certificate) }));
                    return(false);
                }
                if (StoreContainsCertificate(StoreName.Disallowed, certificate))
                {
                    exception = new SecurityTokenValidationException(System.IdentityModel.SR.GetString("X509IsInUntrustedStore", new object[] { System.IdentityModel.SecurityUtils.GetCertificateId(certificate) }));
                    return(false);
                }
                exception = null;
                return(true);
            }
コード例 #4
0
        private async Task <JwtSecurityToken> ValidateTokenAsync(
            string token,
            string issuer,
            string audience,
            ILogger log,
            IConfigurationManager <OpenIdConnectConfiguration> configurationManager,
            CancellationToken ct = default(CancellationToken))
        {
            JwtSecurityToken result = null;

            if (string.IsNullOrEmpty(token))
            {
                log.LogError(new ArgumentNullException(nameof(token)), "ERROR: ValidateToken: token input value is missing.");
            }

            if (string.IsNullOrEmpty(issuer))
            {
                log.LogError(new ArgumentNullException(nameof(issuer)), "ERROR: ValidateToken: issuer input value is missing.");
            }

            if (string.IsNullOrEmpty(audience))
            {
                log.LogError(new ArgumentNullException(nameof(audience)), "ERROR: ValidateToken: audience input value is missing.");
            }

            var discoveryDocument = await configurationManager.GetConfigurationAsync(ct);

            var signingKeys = discoveryDocument.SigningKeys;

            var validationParameters = new TokenValidationParameters
            {
                RequireExpirationTime = true,
                RequireSignedTokens   = true,

                ValidAudience    = audience,
                ValidateAudience = true,

                ValidIssuer    = issuer,
                ValidateIssuer = true,

                ValidateIssuerSigningKey = true,
                IssuerSigningKeys        = signingKeys,

                ValidateLifetime = true,

                // Allow for some drift in server time
                // (a lower value is better; we recommend two minutes or less)
                ClockSkew = TimeSpan.FromMinutes(2),
            };

            var tries = 0;

            while (result == null && tries <= 1)
            {
                try
                {
                    var principal = new JwtSecurityTokenHandler()
                                    .ValidateToken(token, validationParameters, out var rawValidatedToken);

                    if (rawValidatedToken != null)
                    {
                        var validatedToken = (JwtSecurityToken)rawValidatedToken;

                        var expectedAlg = SecurityAlgorithms.RsaSha256; //Okta uses RS256

                        if (validatedToken.Header?.Alg == null || validatedToken.Header?.Alg != expectedAlg)
                        {
                            var tokvalex = new SecurityTokenValidationException("The alg must be RS256.");

                            log.LogError(tokvalex, "ERROR: ValidateToken: SecurityTokenValidationException Ocurred");
                        }
                        else
                        {
                            result = validatedToken;
                        }
                    }
                }
                catch (SecurityTokenSignatureKeyNotFoundException)
                {
                    // This exception is thrown if the signature key of the JWT could not be found.
                    // This could be the case when the issuer changed its signing keys, so we trigger a
                    // refresh and retry validation.
                    _configurationManager.RequestRefresh();

                    tries++;
                }
                catch (SecurityTokenValidationException stvex)
                {
                    log.LogError(stvex, "ERROR: ValidateToken: Token failed validation.");
                }
                catch (ArgumentException argex)
                {
                    log.LogError(argex, "ERROR: ValidateToken: Token was not well-formed or was invalid for some other reason.");
                }
            }

            return(result);
        }
コード例 #5
0
        private async Task <ClaimsPrincipal> ValidateTokenAsync(AuthenticationHeaderValue value, ILogger log)
        {
            ClaimsPrincipal result = null;

            if (value?.Scheme != "Bearer")
            {
                return(null);
            }

            var discoveryDocument = await _configurationManager.GetConfigurationAsync(CancellationToken.None);

            var signingKeys = discoveryDocument.SigningKeys;

            var issuer = Environment.GetEnvironmentVariable("ISSUER");

            var audience = Environment.GetEnvironmentVariable("AUDIENCE");

            var validationParameters = new TokenValidationParameters()
            {
                RequireExpirationTime = true,
                RequireSignedTokens   = true,

                ValidAudience    = audience,
                ValidateAudience = true,

                ValidIssuer    = issuer,
                ValidateIssuer = true,

                ValidateIssuerSigningKey = true,
                IssuerSigningKeys        = signingKeys,

                ValidateLifetime = true,

                // Allow for some drift in server time
                // (a lower value is better; recommend two minutes or less)
                ClockSkew = TimeSpan.FromMinutes(2),
            };

            var tries = 0;

            while (result == null && tries <= 1)
            {
                try
                {
                    var handler = new JwtSecurityTokenHandler();

                    result = handler.ValidateToken(value.Parameter, validationParameters, out var token);

                    if (token != null)
                    {
                        var validatedToken = (JwtSecurityToken)token;

                        var expectedAlg = SecurityAlgorithms.RsaSha256; //Okta uses RS256

                        if (validatedToken.Header?.Alg == null || validatedToken.Header?.Alg != expectedAlg)
                        {
                            var tokenValidationEx = new SecurityTokenValidationException("The alg must be RS256.");

                            log.LogError(tokenValidationEx, "ERROR: SecurityTokenValidationException Ocurred");

                            return(null);
                        }
                    }
                }
                catch (SecurityTokenSignatureKeyNotFoundException)
                {
                    // This exception is thrown if the signature key of the JWT could not be found.
                    // This could be the case when the issuer changed its signing keys, so we trigger a
                    // refresh and retry validation.
                    _configurationManager.RequestRefresh();

                    tries++;
                }
                catch (SecurityTokenValidationException stvex)
                {
                    log.LogError(stvex, "ERROR: ValidateToken: Token failed validation.");
                }
                catch (ArgumentException argex)
                {
                    log.LogError(argex, "ERROR: ValidateToken: Token was not well-formed or was invalid for some other reason.");
                }
            }

            return(result);
        }