/// <summary> /// Validates a JWT request object /// </summary> /// <param name="client">The client</param> /// <param name="jwtTokenString">The JWT</param> /// <returns></returns> public virtual async Task <JwtRequestValidationResult> ValidateAsync(Client client, string jwtTokenString) { if (client == null) { throw new ArgumentNullException(nameof(client)); } if (String.IsNullOrWhiteSpace(jwtTokenString)) { throw new ArgumentNullException(nameof(jwtTokenString)); } var fail = new JwtRequestValidationResult { IsError = true }; List <SecurityKey> trustedKeys; try { trustedKeys = await GetKeysAsync(client); } catch (Exception e) { Logger.LogError(e, "Could not parse client secrets"); return(fail); } if (!trustedKeys.Any()) { Logger.LogError("There are no keys available to validate JWT."); return(fail); } JwtSecurityToken jwtSecurityToken; try { jwtSecurityToken = await ValidateJwtAsync(jwtTokenString, trustedKeys, client); } catch (Exception e) { Logger.LogError(e, "JWT token validation error"); return(fail); } if (jwtSecurityToken.Payload.ContainsKey(OidcConstants.AuthorizeRequest.Request) || jwtSecurityToken.Payload.ContainsKey(OidcConstants.AuthorizeRequest.RequestUri)) { Logger.LogError("JWT payload must not contain request or request_uri"); return(fail); } var payload = await ProcessPayloadAsync(jwtSecurityToken); var result = new JwtRequestValidationResult { IsError = false, Payload = payload }; Logger.LogDebug("JWT request object validation success."); return(result); }
public Task <JwtRequestValidationResult> ValidateAsync(Client client, string jwtTokenString) { if (client == null) { throw new ArgumentNullException(nameof(client)); } if (String.IsNullOrWhiteSpace(jwtTokenString)) { throw new ArgumentNullException(nameof(jwtTokenString)); } var fail = Task.FromResult(new JwtRequestValidationResult { IsError = true }); var enumeratedSecrets = client.ClientSecrets.ToList().AsReadOnly(); List <SecurityKey> trustedKeys; try { trustedKeys = GetKeys(enumeratedSecrets); } catch (Exception e) { _logger.LogError(e, "Could not parse client secrets"); return(fail); } if (!trustedKeys.Any()) { _logger.LogError("There are no keys available to validate JWT."); return(fail); } var tokenValidationParameters = new TokenValidationParameters { IssuerSigningKeys = trustedKeys, ValidateIssuerSigningKey = true, ValidIssuer = client.ClientId, ValidateIssuer = true, ValidAudience = _audienceUri, ValidateAudience = true, RequireSignedTokens = true, RequireExpirationTime = true }; try { var handler = new JwtSecurityTokenHandler(); handler.ValidateToken(jwtTokenString, tokenValidationParameters, out var token); var jwtSecurityToken = (JwtSecurityToken)token; // todo: IdentityModel update if (jwtSecurityToken.Payload.ContainsKey("request") || jwtSecurityToken.Payload.ContainsKey("request_uri")) { _logger.LogError("JWT payload must not contain request or request_uri"); return(fail); } // filter JWT validation values var payload = new Dictionary <string, string>(); foreach (var key in jwtSecurityToken.Payload.Keys) { if (!Constants.Filters.JwtRequestClaimTypesFilter.Contains(key)) { var value = jwtSecurityToken.Payload[key]; if (value is string s) { payload.Add(key, s); } else if (value is JObject jobj) { payload.Add(key, jobj.ToString(Formatting.None)); } else if (value is JArray jarr) { payload.Add(key, jarr.ToString(Formatting.None)); } } } var result = new JwtRequestValidationResult { IsError = false, Payload = payload }; _logger.LogDebug("JWT request object validation success."); return(Task.FromResult(result)); } catch (Exception e) { _logger.LogError(e, "JWT token validation error"); return(fail); } }