/// <summary> /// Reads and validates a token encoded in JSON Compact serialized format. /// </summary> /// <param name="securityToken">A 'JSON Web Token' (JWT) that has been encoded as a JSON object. May be signed using 'JSON Web Signature' (JWS).</param> /// <param name="validationParameters">Contains validation parameters for the <see cref="JwtSecurityToken"/>.</param> /// <param name="validatedToken">The <see cref="JwtSecurityToken"/> 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"/> from the jwt. Does not include the header claims.</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)); } JwtSecurityToken jwt = this.ValidateSignature(securityToken, validationParameters); if (jwt.SigningKey != null) { this.ValidateIssuerSecurityKey(jwt.SigningKey, jwt, validationParameters); } DateTime? notBefore = null; if (jwt.Payload.Nbf != null) { notBefore = new DateTime?(jwt.ValidFrom); } DateTime? expires = null; if (jwt.Payload.Exp != null) { expires = new DateTime?(jwt.ValidTo); } Validators.ValidateTokenReplay(securityToken, expires, validationParameters); if (validationParameters.ValidateLifetime) { if (validationParameters.LifetimeValidator != null) { if (!validationParameters.LifetimeValidator(notBefore: notBefore, expires: expires, securityToken: jwt, validationParameters: validationParameters)) { throw new SecurityTokenInvalidLifetimeException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10230, jwt.ToString())); } } else { ValidateLifetime(notBefore: notBefore, expires: expires, securityToken: jwt, validationParameters: 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 { this.ValidateAudience(jwt.Audiences, 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); }
/// <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)); } // Calling System.IdentityModel.Tokens.SamlSecurityTokenHandler requires Configuration and IssuerTokenResolver be set. Configuration = new SecurityTokenHandlerConfiguration { IssuerTokenResolver = new SecurityKeyResolver(securityToken, validationParameters), MaxClockSkew = validationParameters.ClockSkew, }; SamlSecurityToken samlToken; using (StringReader sr = new StringReader(securityToken)) { using (XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(sr))) { samlToken = ReadToken(reader, validationParameters) as SamlSecurityToken; } } if (samlToken.Assertion == null) { throw new ArgumentException(ErrorMessages.IDX10202); } if (samlToken.Assertion.SigningToken == null && validationParameters.RequireSignedTokens) { throw new SecurityTokenValidationException(ErrorMessages.IDX10213); } 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.LifetimeValidator != null) { validationParameters.LifetimeValidator(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters); } else { ValidateLifetime(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters); } 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) { validationParameters.AudienceValidator(audiences, samlToken, validationParameters); } else { ValidateAudience(audiences, samlToken, validationParameters); } string issuer = null; issuer = samlToken.Assertion.Issuer == null ? null : samlToken.Assertion.Issuer; if (validationParameters.IssuerValidator != null) { issuer = validationParameters.IssuerValidator(issuer, samlToken, validationParameters); } else { issuer = ValidateIssuer( issuer, samlToken, validationParameters); } if (string.IsNullOrWhiteSpace(issuer)) { throw new SecurityTokenInvalidIssuerException(ErrorMessages.IDX10203); } if (samlToken.Assertion.SigningToken != null) { ValidateIssuerSecurityKey(samlToken.Assertion.SigningToken.SecurityKeys[0], samlToken, validationParameters); } ClaimsIdentity claimsIdentity = CreateClaimsIdentity(samlToken, issuer, validationParameters); if (validationParameters.SaveSigninToken) { claimsIdentity.BootstrapContext = new BootstrapContext(securityToken); } validatedToken = samlToken; return new ClaimsPrincipal(claimsIdentity); }
/// <summary> /// Reads and validates a well fromed Saml2 securityToken. /// </summary> /// <param name="securityToken">A Saml2 securityToken.</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.LifetimeValidator != null) { validationParameters.LifetimeValidator(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters); } else { ValidateLifetime(notBefore: notBefore, expires: expires, securityToken: samlToken, validationParameters: validationParameters); } // TODO // need to validate ValidateConfirmationData(subjectConfirmation.SubjectConfirmationData); 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) { validationParameters.AudienceValidator(audiences, samlToken, validationParameters); } else { ValidateAudience(audiences, samlToken, validationParameters); } string issuer = samlToken.Assertion.Issuer != null ? samlToken.Assertion.Issuer.Value : null; if (validationParameters.IssuerValidator != null) { issuer = validationParameters.IssuerValidator(issuer, samlToken, validationParameters); } else { issuer = ValidateIssuer( issuer, samlToken, validationParameters); } if (string.IsNullOrWhiteSpace(issuer)) { throw new SecurityTokenInvalidIssuerException(ErrorMessages.IDX10203); } if (samlToken.IssuerToken != null) { ValidateIssuerSecurityKey(samlToken.IssuerToken.SecurityKeys[0], samlToken, validationParameters); } ClaimsIdentity claimsIdentity = CreateClaimsIdentity(samlToken, issuer, validationParameters); if (validationParameters.SaveSigninToken) { claimsIdentity.BootstrapContext = new BootstrapContext(securityToken); } validatedToken = samlToken; return new ClaimsPrincipal(claimsIdentity); }
protected 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; }