/// <summary>
        /// Reads and validates a well fromed Saml2 token.
        /// </summary>
        /// <param name="securityToken">A Saml2 token.</param>
        /// <param name="validationParameters">Contains data and information needed for validation.</param>
        /// <param name="validatedToken">The <see cref="SamlSecurityToken"/> that was validated.</param>
        /// <exception cref="ArgumentNullException">'securityToken' is null or whitespace.</exception>
        /// <exception cref="ArgumentNullException">'validationParameters' is null.</exception>
        /// <exception cref="ArgumentException">'securityToken.Length' > <see cref="MaximumTokenSizeInBytes"/>.</exception>
        /// <returns>A <see cref="ClaimsPrincipal"/> generated from the claims in the Saml2 securityToken.</returns>
        public virtual ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            validatedToken = null;
            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));
            }

            Saml2SecurityToken samlToken;

            using (StringReader sr = new StringReader(securityToken))
            {
                using (XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(sr)))
                {
                    samlToken = (new Saml2Handler()
                    {
                        Configuration = new SecurityTokenHandlerConfiguration
                        {
                            IssuerTokenResolver = new SecurityKeyResolver(securityToken, validationParameters),
                            MaxClockSkew = validationParameters.ClockSkew,
                            ServiceTokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(validationParameters.ClientDecryptionTokens, true),
                        }
                    }).ReadToken(reader) as Saml2SecurityToken;
                }
            }

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

            if (samlToken.Assertion == null)
            {
                throw new ArgumentException(ErrorMessages.IDX10202);
            }

            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);
                }
            }

            // TODO
            // need to validate   ValidateConfirmationData(subjectConfirmation.SubjectConfirmationData);

            if (validationParameters.ValidateAudience)
            {
                List <string> audiences = new List <string>();
                if (samlToken.Assertion.Conditions != null && samlToken.Assertion.Conditions.AudienceRestrictions != null)
                {
                    foreach (Saml2AudienceRestriction restriction in samlToken.Assertion.Conditions.AudienceRestrictions)
                    {
                        if (restriction == null)
                        {
                            continue;
                        }

                        foreach (Uri uri in restriction.Audiences)
                        {
                            if (uri == null)
                            {
                                continue;
                            }

                            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 = samlToken.Assertion.Issuer != null ? samlToken.Assertion.Issuer.Value : null;

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

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

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

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

            validatedToken = samlToken;
            return(new ClaimsPrincipal(identity));
        }
Beispiel #2
0
        /// <summary>
        /// Determines if an issuer found in a <see cref="SecurityToken"/> is valid.
        /// </summary>
        /// <param name="issuer">The issuer to validate</param>
        /// <param name="securityToken">The <see cref="SecurityToken"/> that is being validated.</param>
        /// <param name="validationParameters"><see cref="TokenValidationParameters"/> required for validation.</param>
        /// <returns>The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity".</returns>
        /// <exception cref="ArgumentNullException">If 'vaidationParameters' is null.</exception>
        /// <exception cref="ArgumentNullException">If 'issuer' is null or whitespace and <see cref="TokenValidationParameters.ValidateIssuer"/> is true.</exception>
        /// <exception cref="SecurityTokenInvalidIssuerException">If <see cref="TokenValidationParameters.ValidIssuer"/> is null or whitespace and <see cref="TokenValidationParameters.ValidIssuers"/> is null.</exception>
        /// <exception cref="SecurityTokenInvalidIssuerException">If 'issuer' failed to matched either <see cref="TokenValidationParameters.ValidIssuer"/> or one of <see cref="TokenValidationParameters.ValidIssuers"/>.</exception>
        /// <remarks>An EXACT match is required.</remarks>
        public static string ValidateIssuer(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            if (validationParameters == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(validationParameters));
            }

            if (validationParameters.IssuerValidator != null)
            {
                return(validationParameters.IssuerValidator(issuer, securityToken, validationParameters));
            }

            if (!validationParameters.ValidateIssuer)
            {
                LogHelper.LogInformation(LogMessages.IDX10235);
                return(issuer);
            }

            if (string.IsNullOrWhiteSpace(issuer))
            {
                throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX10211)
                {
                    InvalidIssuer = issuer
                });
            }

            // Throw if all possible places to validate against are null or empty
            if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer) && (validationParameters.ValidIssuers == null))
            {
                throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX10204)
                {
                    InvalidIssuer = issuer
                });
            }

            if (string.Equals(validationParameters.ValidIssuer, issuer, StringComparison.Ordinal))
            {
                LogHelper.LogInformation(LogMessages.IDX10236, issuer);
                return(issuer);
            }

            if (null != validationParameters.ValidIssuers)
            {
                foreach (string str in validationParameters.ValidIssuers)
                {
                    if (string.IsNullOrEmpty(str))
                    {
                        LogHelper.LogInformation(LogMessages.IDX10235);
                        continue;
                    }

                    if (string.Equals(str, issuer, StringComparison.Ordinal))
                    {
                        LogHelper.LogInformation(LogMessages.IDX10236, issuer);
                        return(issuer);
                    }
                }
            }

            throw LogHelper.LogExceptionMessage(
                      new SecurityTokenInvalidIssuerException(LogHelper.FormatInvariant(LogMessages.IDX10205, issuer, (validationParameters.ValidIssuer ?? "null"), Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers)))
            {
                InvalidIssuer = issuer
            });
        }