public virtual async Task <TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null) { Logger.Info("Start access token validation"); _log.ExpectedScope = expectedScope; _log.ValidateLifetime = true; TokenValidationResult result; if (token.Contains(".")) { _log.AccessTokenType = AccessTokenType.Jwt.ToString(); result = await ValidateJwtAsync( token, string.Format(Constants.AccessTokenAudience, _options.IssuerUri.EnsureTrailingSlash()), new X509SecurityKey(_options.SigningCertificate)); } else { _log.AccessTokenType = AccessTokenType.Reference.ToString(); result = await ValidateReferenceAccessTokenAsync(token); } if (_options.LoggingOptions.IncludeSensitiveDataInLogs) { _log.Claims = result.Claims.ToClaimsDictionary(); } if (result.IsError) { return(result); } if (expectedScope.IsPresent()) { var scope = result.Claims.FirstOrDefault(c => c.Type == Constants.ClaimTypes.Scope && c.Value == expectedScope); if (scope == null) { LogError(string.Format("Checking for expected scope {0} failed", expectedScope)); return(Invalid(Constants.ProtectedResourceErrors.InsufficientScope)); } } var customResult = await _customValidator.ValidateAccessTokenAsync(result); if (customResult.IsError) { LogError("Custom validator failed: " + customResult.Error ?? "unknown"); return(customResult); } // add claims again after custom validation if (_options.LoggingOptions.IncludeSensitiveDataInLogs) { _log.Claims = customResult.Claims.ToClaimsDictionary(); } LogSuccess(); return(customResult); }
public virtual async Task <TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null) { Logger.Info("Start access token validation"); Logger.Debug("Token: " + token); TokenValidationResult result; if (token.Contains(".")) { Logger.InfoFormat("Validating a JWT access token"); result = await ValidateJwtAsync( token, string.Format(Constants.AccessTokenAudience, _options.IssuerUri.EnsureTrailingSlash()), new X509SecurityKey(_options.SigningCertificate)); } else { Logger.InfoFormat("Validating a reference access token"); result = await ValidateReferenceAccessTokenAsync(token); } if (result.IsError) { return(result); } if (expectedScope.IsPresent()) { var scope = result.Claims.FirstOrDefault(c => c.Type == Constants.ClaimTypes.Scope && c.Value == expectedScope); if (scope == null) { Logger.InfoFormat("Checking for expected scope {0} failed", expectedScope); return(Invalid(Constants.ProtectedResourceErrors.InsufficientScope)); } Logger.InfoFormat("Checking for expected scope {0} succeeded", expectedScope); } Logger.Debug("Calling custom token validator"); var customResult = await _customValidator.ValidateAccessTokenAsync(result); if (customResult.IsError) { Logger.Error("Custom validator failed: " + customResult.Error ?? "unknown"); } return(customResult); }
public virtual async Task <TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null) { Logger.Info("Start access token validation"); Logger.Debug("Token: " + token); var result = new TokenValidationResult(); if (token.Contains(".")) { Logger.InfoFormat("Validating a JWT access token"); result = await ValidateJwtAccessTokenAsync(token); } else { Logger.InfoFormat("Validating a reference access token"); result = await ValidateReferenceAccessTokenAsync(token); } if (expectedScope.IsPresent()) { var scope = result.Claims.FirstOrDefault(c => c.Type == Constants.ClaimTypes.Scope && c.Value == expectedScope); if (scope == null) { Logger.InfoFormat("Checking for expected scope {0} failed", expectedScope); return(Invalid(Constants.ProtectedResourceErrors.InsufficientScope)); } Logger.InfoFormat("Checking for expected scope {0} succeeded", expectedScope); } Logger.Debug("Calling custom token validator"); var customResult = await _customValidator.ValidateAccessTokenAsync(result, _settings, _clients, _users); if (customResult.IsError) { Logger.Error("Custom validator failed: " + customResult.Error ?? "unknown"); } return(customResult); }
public virtual async Task <TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null) { _logger.LogTrace("Start access token validation"); _log.ExpectedScope = expectedScope; _log.ValidateLifetime = true; TokenValidationResult result; if (token.Contains(".")) { if (token.Length > _options.InputLengthRestrictions.Jwt) { _logger.LogError("JWT too long"); return(new TokenValidationResult { IsError = true, Error = OidcConstants.ProtectedResourceErrors.InvalidToken, ErrorDescription = "Token too long" }); } _log.AccessTokenType = AccessTokenType.Jwt.ToString(); result = await ValidateJwtAsync( token, string.Format(Constants.AccessTokenAudience, _context.HttpContext.GetIssuerUri().EnsureTrailingSlash()), await _keys.GetValidationKeysAsync()); } else { if (token.Length > _options.InputLengthRestrictions.TokenHandle) { _logger.LogError("token handle too long"); return(new TokenValidationResult { IsError = true, Error = OidcConstants.ProtectedResourceErrors.InvalidToken, ErrorDescription = "Token too long" }); } _log.AccessTokenType = AccessTokenType.Reference.ToString(); result = await ValidateReferenceAccessTokenAsync(token); } _log.Claims = result.Claims.ToClaimsDictionary(); if (result.IsError) { return(result); } if (expectedScope.IsPresent()) { var scope = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Scope && c.Value == expectedScope); if (scope == null) { LogError(string.Format("Checking for expected scope {0} failed", expectedScope)); return(Invalid(OidcConstants.ProtectedResourceErrors.InsufficientScope)); } } var customResult = await _customValidator.ValidateAccessTokenAsync(result); if (customResult.IsError) { LogError("Custom validator failed: " + (customResult.Error ?? "unknown")); return(customResult); } // add claims again after custom validation _log.Claims = customResult.Claims.ToClaimsDictionary(); LogSuccess(); return(customResult); }
public async Task <TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null) { _logger.LogTrace("Start access token validation"); _log.ExpectedScope = expectedScope; _log.ValidateLifetime = true; TokenValidationResult result; if (token.Contains(".")) { if (token.Length > _options.InputLengthRestrictions.Jwt) { _logger.LogError("JWT too long"); return(new TokenValidationResult { IsError = true, Error = OidcConstants.ProtectedResourceErrors.InvalidToken, ErrorDescription = "Token too long" }); } _log.AccessTokenType = AccessTokenType.Jwt.ToString(); result = await ValidateJwtAsync( token, string.Format(Constants.AccessTokenAudience, _context.HttpContext.GetIdentityServerIssuerUri().EnsureTrailingSlash()), await _keys.GetValidationKeysAsync()); } else { if (token.Length > _options.InputLengthRestrictions.TokenHandle) { _logger.LogError("token handle too long"); return(new TokenValidationResult { IsError = true, Error = OidcConstants.ProtectedResourceErrors.InvalidToken, ErrorDescription = "Token too long" }); } _log.AccessTokenType = AccessTokenType.Reference.ToString(); result = await ValidateReferenceAccessTokenAsync(token); } _log.Claims = result.Claims.ToClaimsDictionary(); if (result.IsError) { return(result); } // make sure client is still active (if client_id claim is present) var clientClaim = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.ClientId); if (clientClaim != null) { var client = await _clients.FindEnabledClientByIdAsync(clientClaim.Value); if (client == null) { _logger.LogError("Client deleted or disabled: {clientId}", clientClaim.Value); result.IsError = true; result.Error = OidcConstants.ProtectedResourceErrors.InvalidToken; result.Claims = null; return(result); } } // make sure user is still active (if sub claim is present) var subClaim = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject); if (subClaim != null) { var principal = Principal.Create("tokenvalidator", result.Claims.ToArray()); if (result.ReferenceTokenId.IsPresent()) { principal.Identities.First().AddClaim(new Claim(JwtClaimTypes.ReferenceTokenId, result.ReferenceTokenId)); } var isActiveCtx = new IsActiveContext(principal, result.Client, IdentityServerConstants.ProfileIsActiveCallers.AccessTokenValidation); await _profile.IsActiveAsync(isActiveCtx); if (isActiveCtx.IsActive == false) { _logger.LogError("User marked as not active: {subject}", subClaim.Value); result.IsError = true; result.Error = OidcConstants.ProtectedResourceErrors.InvalidToken; result.Claims = null; return(result); } } // check expected scope(s) if (expectedScope.IsPresent()) { var scope = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Scope && c.Value == expectedScope); if (scope == null) { LogError(string.Format("Checking for expected scope {0} failed", expectedScope)); return(Invalid(OidcConstants.ProtectedResourceErrors.InsufficientScope)); } } _logger.LogDebug("Calling into custom token validator: {type}", _customValidator.GetType().FullName); var customResult = await _customValidator.ValidateAccessTokenAsync(result); if (customResult.IsError) { LogError("Custom validator failed: " + (customResult.Error ?? "unknown")); return(customResult); } // add claims again after custom validation _log.Claims = customResult.Claims.ToClaimsDictionary(); LogSuccess(); return(customResult); }