private async Task ExtractSoftwareStatement(JObject jObj) { var softwareStatement = jObj.GetSoftwareStatement(); if (string.IsNullOrWhiteSpace(softwareStatement)) { return; } if (!_jwtParser.IsJwsToken(softwareStatement)) { throw new OAuthException(ErrorCodes.INVALID_SOFTWARE_STATEMENT, ErrorMessages.BAD_JWS_SOFTWARE_STATEMENT); } SimpleIdServer.Jwt.Jws.JwsPayload jwsPayload; SimpleIdServer.Jwt.Jws.JwsHeader header; try { jwsPayload = _jwtParser.ExtractJwsPayload(softwareStatement); header = _jwtParser.ExtractJwsHeader(softwareStatement); if (jwsPayload == null) { throw new OAuthException(ErrorCodes.INVALID_SOFTWARE_STATEMENT, ErrorMessages.BAD_JWS_SOFTWARE_STATEMENT); } } catch { throw new OAuthException(ErrorCodes.INVALID_SOFTWARE_STATEMENT, ErrorMessages.BAD_JWS_SOFTWARE_STATEMENT); } var issuer = jwsPayload.GetIssuer(); var trustedParty = OauthHostOptions.SoftwareStatementTrustedParties.FirstOrDefault(s => s.Iss == issuer); if (trustedParty == null) { throw new OAuthException(ErrorCodes.INVALID_SOFTWARE_STATEMENT, ErrorMessages.BAD_ISSUER_SOFTWARE_STATEMENT); } using (var httpClient = _httpClientFactory.GetHttpClient()) { var json = await httpClient.GetStringAsync(trustedParty.JwksUrl); var keysJson = JObject.Parse(json)["keys"].ToString(); var jsonWebKeys = JsonConvert.DeserializeObject <JArray>(keysJson).Select(k => SimpleIdServer.Jwt.JsonWebKey.Deserialize(k.ToString())); var jsonWebKey = jsonWebKeys.FirstOrDefault(j => j.Kid == header.Kid); jwsPayload = _jwtParser.Unsign(softwareStatement, jsonWebKey); if (jwsPayload == null) { throw new OAuthException(ErrorCodes.INVALID_SOFTWARE_STATEMENT, ErrorMessages.BAD_SOFTWARE_STATEMENT_SIGNATURE); } foreach (var kvp in jwsPayload) { if (jObj.ContainsKey(kvp.Key)) { jObj.Remove(kvp.Key); } jObj.Add(kvp.Key, JToken.FromObject(kvp.Value)); } } }