Ejemplo n.º 1
0
        public override ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            try
            {
                var jwt = this.ValidateSignature(securityToken, validationParameters);
                if (validationParameters.ValidateAudience)
                {
                    if (validationParameters.AudienceValidator != null)
                    {
                        if (!validationParameters.AudienceValidator(jwt.Audiences, jwt, validationParameters))
                        {
                            throw new SecurityTokenInvalidAudienceException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10231, jwt.ToString()));
                        }
                    }
                    else
                    {
                        base.ValidateAudience(validationParameters.ValidAudiences, jwt, validationParameters);
                    }
                }

                string issuer = jwt.Issuer;
                if (validationParameters.ValidateIssuer)
                {
                    if (validationParameters.IssuerValidator != null)
                    {
                        issuer = validationParameters.IssuerValidator(issuer, jwt, validationParameters);
                    }
                    else
                    {
                        issuer = ValidateIssuer(issuer, jwt, validationParameters);
                    }
                }

                if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jwt.Actor))
                {
                    SecurityToken actor = null;
                    ValidateToken(jwt.Actor, validationParameters, out actor);
                }

                ClaimsIdentity identity = this.CreateClaimsIdentity(jwt, issuer, validationParameters);
                if (validationParameters.SaveSigninToken)
                {
                    identity.BootstrapContext = new BootstrapContext(securityToken);
                }

                validatedToken = jwt;
                return(new ClaimsPrincipal(identity));
            }
            catch (Exception ex)
            {
                Debug.WriteLine("JWT EXCEPTION: " + ex);
                throw;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads and validates a well formed <see cref="SamlSecurityToken"/>.
        /// </summary>
        /// <param name="securityToken">A string containing a well formed securityToken.</param>
        /// <param name="validationParameters">Contains data and information needed for validation.</param>
        /// <param name="validatedToken">The <see cref="SecurityToken"/> that was validated.</param>
        /// <exception cref="ArgumentNullException">'securityToken' is null or whitespace.</exception>
        /// <exception cref="ArgumentNullException">'validationParameters' is null.</exception>
        /// <exception cref="SecurityTokenException">'securityToken.Length' > <see cref="MaximumTokenSizeInBytes"/>.</exception>
        /// <returns>A <see cref="ClaimsPrincipal"/> generated from the claims in the Saml securityToken.</returns>
        public virtual ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            if (string.IsNullOrWhiteSpace(securityToken))
            {
                throw LogHelper.LogArgumentNullException("securityToken");
            }


            if (validationParameters == null)
            {
                throw LogHelper.LogArgumentNullException("validationParameters");
            }

            if (securityToken.Length > MaximumTokenSizeInBytes)
            {
                throw LogHelper.LogException <ArgumentException>(LogMessages.IDX10209, securityToken.Length, MaximumTokenSizeInBytes);
            }

            SamlSecurityToken samlToken;

            using (StringReader sr = new StringReader(securityToken))
            {
                using (XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(sr)))
                {
                    samlToken = ReadToken(reader, validationParameters) as SamlSecurityToken;
                }
            }

            if (samlToken.SigningKey == null && validationParameters.RequireSignedTokens)
            {
                throw new SecurityTokenValidationException(LogMessages.IDX10213);
            }

            DateTime?notBefore = null;
            DateTime?expires   = null;

            if (samlToken.Conditions != null)
            {
                notBefore = samlToken.Conditions.NotBefore;
                expires   = samlToken.Conditions.Expires;
            }

            Validators.ValidateTokenReplay(securityToken, expires, validationParameters);

            if (validationParameters.ValidateLifetime)
            {
                if (validationParameters.LifetimeValidator != null)
                {
                    if (!validationParameters.LifetimeValidator(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters))
                    {
                        throw LogHelper.LogException <SecurityTokenInvalidLifetimeException>(LogMessages.IDX10230, securityToken);
                    }
                }
                else
                {
                    ValidateLifetime(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters);
                }
            }

            if (validationParameters.ValidateAudience)
            {
                List <string> audiences = new List <string>();
                if (samlToken.Conditions != null && samlToken.Conditions.Conditions != null)
                {
                    foreach (SamlCondition condition in samlToken.Conditions.Conditions)
                    {
                        SamlAudienceRestrictionCondition audienceRestriction = condition as SamlAudienceRestrictionCondition;
                        if (null == audienceRestriction)
                        {
                            continue;
                        }

                        foreach (Uri uri in audienceRestriction.Audiences)
                        {
                            audiences.Add(uri.OriginalString);
                        }
                    }
                }

                if (validationParameters.AudienceValidator != null)
                {
                    if (!validationParameters.AudienceValidator(audiences, samlToken, validationParameters))
                    {
                        throw LogHelper.LogException <SecurityTokenInvalidAudienceException>(LogMessages.IDX10231, securityToken);
                    }
                }
                else
                {
                    ValidateAudience(audiences, samlToken, validationParameters);
                }
            }

            string issuer = null;

            issuer = samlToken.Issuer == null ? null : samlToken.Issuer;

            if (validationParameters.ValidateIssuer)
            {
                if (validationParameters.IssuerValidator != null)
                {
                    issuer = validationParameters.IssuerValidator(issuer, samlToken, validationParameters);
                }
                else
                {
                    issuer = ValidateIssuer(issuer, samlToken, validationParameters);
                }
            }

            if (samlToken.SigningKey != null)
            {
                ValidateIssuerSecurityKey(samlToken.SigningKey, samlToken, validationParameters);
            }

            ClaimsIdentity identity = CreateClaimsIdentity(samlToken, issuer, validationParameters);

            if (validationParameters.SaveSigninToken)
            {
                identity.BootstrapContext = securityToken;
            }

            validatedToken = samlToken;
            return(new ClaimsPrincipal(identity));
        }
Ejemplo n.º 3
0
        public SecurityToken ValidateToken(string securityToken, TokenValidationParameters validationParameters)
        {
            ////////////////////////////////
            // Copied from MS Source Code //
            ////////////////////////////////

            if (string.IsNullOrWhiteSpace(securityToken))
            {
                throw new ArgumentNullException(nameof(securityToken));
            }

            if (validationParameters == null)
            {
                throw new ArgumentNullException(nameof(validationParameters));
            }

            if (securityToken.Length > MaximumTokenSizeInBytes)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10209,
                                                          securityToken.Length, MaximumTokenSizeInBytes));
            }

            var jwt = ValidateSignature(securityToken, validationParameters);

            if (jwt.SigningKey != null)
            {
                ValidateIssuerSecurityKey(jwt.SigningKey, jwt, validationParameters);
            }

            DateTime?notBefore = null;

            if (jwt.Payload.Nbf != null)
            {
                notBefore = jwt.ValidFrom;
            }

            DateTime?expires = null;

            if (jwt.Payload.Exp != null)
            {
                expires = jwt.ValidTo;
            }

            Validators.ValidateTokenReplay(securityToken, expires, validationParameters);
            if (validationParameters.ValidateLifetime)
            {
                if (validationParameters.LifetimeValidator != null)
                {
                    if (!validationParameters.LifetimeValidator(notBefore, expires, jwt, validationParameters))
                    {
                        throw new SecurityTokenInvalidLifetimeException(string.Format(CultureInfo.InvariantCulture,
                                                                                      ErrorMessages.IDX10230, jwt));
                    }
                }
                else
                {
                    ValidateLifetime(notBefore, expires, jwt, validationParameters);
                }
            }

            if (validationParameters.ValidateAudience)
            {
                if (validationParameters.AudienceValidator != null)
                {
                    if (!validationParameters.AudienceValidator(jwt.Audiences, jwt, validationParameters))
                    {
                        throw new SecurityTokenInvalidAudienceException(string.Format(CultureInfo.InvariantCulture,
                                                                                      ErrorMessages.IDX10231, jwt));
                    }
                }
                else
                {
                    ValidateAudience(jwt.Audiences, jwt, validationParameters);
                }
            }

            var issuer = jwt.Issuer;

            if (validationParameters.ValidateIssuer)
            {
                issuer = validationParameters.IssuerValidator != null
                    ? validationParameters.IssuerValidator(issuer, jwt, validationParameters)
                    : ValidateIssuer(issuer, jwt, validationParameters);
            }

            if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jwt.Actor))
            {
                SecurityToken actor;
                ValidateToken(jwt.Actor, validationParameters, out actor);
            }

            return(jwt);
        }
Ejemplo n.º 4
0
        protected SecurityToken ValidateToken(string securityToken, TokenValidationParameters validationParameters, bool disableSignatureValidation)
        {
            ////////////////////////////////
            // Copied from MS Source Code //
            ////////////////////////////////

            if (string.IsNullOrWhiteSpace(securityToken))
            {
                throw new ArgumentNullException(nameof(securityToken));
            }

            if (validationParameters == null)
            {
                throw new ArgumentNullException(nameof(validationParameters));
            }

            if (securityToken.Length > MaximumTokenSizeInBytes)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Constants.ErrorMessages.IDX10209,
                                                          securityToken.Length, MaximumTokenSizeInBytes));
            }

            JwtSecurityToken jwt;

            if (!disableSignatureValidation)
            {
                // For access & id tokens, parse the token and validate signature.
                jwt = ValidateSignature(securityToken, validationParameters);

                if (jwt.SigningKey != null)
                {
                    ValidateIssuerSecurityKey(jwt.SigningKey, jwt, validationParameters);
                }
            }
            else
            {
                // Disabling signature for refresh tokens.
                // This is an option that can be used to fix compatibility with Keycloak v4.5 that switched to use HS256 encryption for Refresh tokens (before it as RS256, the same as for Access tokens)
                // Refresh tokens should not be necessary to validate, as they should only be used by sending it back to Keycloak server when necessary. Keycloak server itself validates refresh tokens. The applications should not use the information in the Refresh token.
                // Ref: https://issues.jboss.org/browse/KEYCLOAK-4622
                jwt = ReadJwtToken(securityToken);
            }

            DateTime?notBefore = null;

            if (jwt.Payload.Nbf != null)
            {
                notBefore = jwt.ValidFrom;
            }

            DateTime?expires = null;

            if (jwt.Payload.Exp != null)
            {
                expires = jwt.ValidTo;
            }

            Validators.ValidateTokenReplay(securityToken, expires, validationParameters);
            if (validationParameters.ValidateLifetime)
            {
                if (validationParameters.LifetimeValidator != null)
                {
                    if (!validationParameters.LifetimeValidator(notBefore, expires, jwt, validationParameters))
                    {
                        throw new SecurityTokenInvalidLifetimeException(string.Format(CultureInfo.InvariantCulture,
                                                                                      Constants.ErrorMessages.IDX10230, jwt));
                    }
                }
                else
                {
                    ValidateLifetime(notBefore, expires, jwt, validationParameters);
                }
            }

            if (validationParameters.ValidateAudience)
            {
                if (validationParameters.AudienceValidator != null)
                {
                    if (!validationParameters.AudienceValidator(jwt.Audiences, jwt, validationParameters))
                    {
                        throw new SecurityTokenInvalidAudienceException(string.Format(CultureInfo.InvariantCulture,
                                                                                      Constants.ErrorMessages.IDX10231, jwt));
                    }
                }
                else
                {
                    ValidateAudience(jwt.Audiences, jwt, validationParameters);
                }
            }

            var issuer = jwt.Issuer;

            if (validationParameters.ValidateIssuer)
            {
                issuer = validationParameters.IssuerValidator != null
                    ? validationParameters.IssuerValidator(issuer, jwt, validationParameters)
                    : ValidateIssuer(issuer, jwt, validationParameters);
            }

            if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jwt.Actor))
            {
                SecurityToken actor;
                ValidateToken(jwt.Actor, validationParameters, out actor);
            }

            return(jwt);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Reads and validates a well formed <see cref="SamlSecurityToken"/>.
        /// </summary>
        /// <param name="securityToken">A string containing a well formed securityToken.</param>
        /// <param name="validationParameters">Contains data and information needed for validation.</param>
        /// <param name="validatedToken">The <see cref="Saml2SecurityToken"/> that was validated.</param>
        /// <exception cref="ArgumentNullException">'securityToken' is null or whitespace.</exception>
        /// <exception cref="ArgumentNullException">'validationParameters' is null.</exception>
        /// <exception cref="SecurityTokenException">'securityToken.Length' > <see cref="MaximumTokenSizeInBytes"/>.</exception>
        /// <returns>A <see cref="ClaimsPrincipal"/> generated from the claims in the Saml securityToken.</returns>
        public virtual ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            if (string.IsNullOrWhiteSpace(securityToken))
            {
                throw new ArgumentNullException("securityToken");
            }

            if (validationParameters == null)
            {
                throw new ArgumentNullException("validationParameters");
            }

            if (securityToken.Length > MaximumTokenSizeInBytes)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10209, securityToken.Length, MaximumTokenSizeInBytes));
            }

            SecurityKeyResolver issuerTokenResolver = new SecurityKeyResolver(securityToken, validationParameters);

            // Calling System.IdentityModel.Tokens.SamlSecurityTokenHandler requires Configuration and IssuerTokenResolver be set.
            Configuration = new SecurityTokenHandlerConfiguration
            {
                IssuerTokenResolver = issuerTokenResolver,
                MaxClockSkew        = validationParameters.ClockSkew,
            };

            try
            {
                SamlSecurityToken samlToken;
                using (StringReader sr = new StringReader(securityToken))
                {
                    using (XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(sr)))
                    {
                        samlToken = ReadToken(reader, validationParameters) as SamlSecurityToken;
                    }
                }

                if (samlToken == null)
                {
                    throw new SecurityTokenValidationException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10201, securityToken));
                }

                if (samlToken.Assertion == null)
                {
                    throw new SecurityTokenValidationException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10202, securityToken));
                }

                if (samlToken.Assertion.SigningToken == null && validationParameters.RequireSignedTokens)
                {
                    throw new SecurityTokenValidationException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10213, securityToken));
                }

                DateTime?notBefore = null;
                DateTime?expires   = null;
                if (samlToken.Assertion.Conditions != null)
                {
                    notBefore = samlToken.Assertion.Conditions.NotBefore;
                    expires   = samlToken.Assertion.Conditions.NotOnOrAfter;
                }

                Validators.ValidateTokenReplay(securityToken, expires, validationParameters);

                if (validationParameters.ValidateLifetime)
                {
                    if (validationParameters.LifetimeValidator != null)
                    {
                        if (!validationParameters.LifetimeValidator(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters))
                        {
                            throw new SecurityTokenInvalidLifetimeException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10230, securityToken));
                        }
                    }
                    else
                    {
                        ValidateLifetime(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters);
                    }
                }

                if (validationParameters.ValidateAudience)
                {
                    List <string> audiences = new List <string>();
                    if (samlToken.Assertion.Conditions != null && samlToken.Assertion.Conditions.Conditions != null)
                    {
                        foreach (SamlCondition condition in samlToken.Assertion.Conditions.Conditions)
                        {
                            SamlAudienceRestrictionCondition audienceRestriction = condition as SamlAudienceRestrictionCondition;
                            if (null == audienceRestriction)
                            {
                                continue;
                            }

                            foreach (Uri uri in audienceRestriction.Audiences)
                            {
                                audiences.Add(uri.OriginalString);
                            }
                        }
                    }

                    if (validationParameters.AudienceValidator != null)
                    {
                        if (!validationParameters.AudienceValidator(audiences, samlToken, validationParameters))
                        {
                            throw new SecurityTokenInvalidAudienceException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10231, securityToken));
                        }
                    }
                    else
                    {
                        ValidateAudience(audiences, samlToken, validationParameters);
                    }
                }

                string issuer = null;
                issuer = samlToken.Assertion.Issuer == null ? null : samlToken.Assertion.Issuer;

                if (validationParameters.ValidateIssuer)
                {
                    if (validationParameters.IssuerValidator != null)
                    {
                        issuer = validationParameters.IssuerValidator(issuer, samlToken, validationParameters);
                    }
                    else
                    {
                        issuer = ValidateIssuer(issuer, samlToken, validationParameters);
                    }
                }

                if (samlToken.Assertion.SigningToken != null)
                {
                    ValidateIssuerSecurityKey(samlToken.Assertion.SigningToken.SecurityKeys[0], samlToken, validationParameters);
                }

                ClaimsIdentity identity = CreateClaimsIdentity(samlToken, issuer, validationParameters);
                if (validationParameters.SaveSigninToken)
                {
                    identity.BootstrapContext = new BootstrapContext(securityToken);
                }

                validatedToken = samlToken;
                return(new ClaimsPrincipal(identity));
            }
            catch (SignatureVerificationFailedException ex)
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(securityToken);
                XmlNodeList keyInfoList = xmlDoc.GetElementsByTagName(SamlConstants.KeyInfo);
                if (keyInfoList.Count > 0 &&
                    (validationParameters.IssuerSigningKey != null ||
                     validationParameters.IssuerSigningKeys != null ||
                     validationParameters.IssuerSigningToken != null ||
                     validationParameters.IssuerSigningTokens != null ||
                     validationParameters.IssuerSigningKeyResolver != null))
                {
                    XmlNode keyInfoNode = keyInfoList.Item(0);
                    if (String.IsNullOrEmpty(keyInfoNode.InnerXml))
                    {
                        // KeyInfo element is empty.
                        throw;
                    }
                    else
                    {
                        if (issuerTokenResolver.IsKeyMatched)
                        {
                            // keyInfo in token matched with key(s) in validationParameters. This usually means the token was compromised.
                            throw;
                        }
                        else
                        {
                            // KeyInfo in token didn't match with key(s) in validationParameters. This means the user should refresh the key material.
                            throw new SecurityTokenSignatureKeyNotFoundException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10506, securityToken), ex);
                        }
                    }
                }
                else
                {
                    // Missing KeyInfo element or validation parameters' SigningKey/SigningKeys/SigningToken/SigningTokens/IssuerSigningKeyResolver.
                    throw;
                }
            }
        }
Ejemplo n.º 6
0
 public static void ValidateAudience(IEnumerable <string> audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
 {
     if (validationParameters == null)
     {
         throw LogHelper.LogArgumentNullException("validationParameters");
     }
     if (!validationParameters.ValidateAudience)
     {
         LogHelper.LogWarning("IDX10233: ValidateAudience property on ValidationParameters is set to false. Exiting without validating the audience.");
         return;
     }
     if (validationParameters.AudienceValidator != null)
     {
         if (!validationParameters.AudienceValidator(audiences, securityToken, validationParameters))
         {
             throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogHelper.FormatInvariant("IDX10231: Audience validation failed. Delegate returned false, securitytoken: '{0}'.", securityToken))
             {
                 InvalidAudience = SerializeAsSingleCommaDelimitedString(audiences)
             });
         }
         return;
     }
     if (audiences == null)
     {
         throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException("IDX10207: Unable to validate audience. The 'audiences' parameter is null.")
         {
             InvalidAudience = null
         });
     }
     if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience) && validationParameters.ValidAudiences == null)
     {
         throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException("IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null.")
         {
             InvalidAudience = SerializeAsSingleCommaDelimitedString(audiences)
         });
     }
     foreach (string audience in audiences)
     {
         if (string.IsNullOrWhiteSpace(audience))
         {
             continue;
         }
         if (validationParameters.ValidAudiences != null)
         {
             foreach (string validAudience in validationParameters.ValidAudiences)
             {
                 if (string.Equals(audience, validAudience, StringComparison.Ordinal))
                 {
                     LogHelper.LogInformation("IDX10234: Audience Validated.Audience: '{0}'", audience);
                     return;
                 }
             }
         }
         if (!string.IsNullOrWhiteSpace(validationParameters.ValidAudience) && string.Equals(audience, validationParameters.ValidAudience, StringComparison.Ordinal))
         {
             LogHelper.LogInformation("IDX10234: Audience Validated.Audience: '{0}'", audience);
             return;
         }
     }
     throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidAudienceException(LogHelper.FormatInvariant("IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudience: '{1}' or validationParameters.ValidAudiences: '{2}'.", SerializeAsSingleCommaDelimitedString(audiences), validationParameters.ValidAudience ?? "null", SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences)))
     {
         InvalidAudience = SerializeAsSingleCommaDelimitedString(audiences)
     });
 }