private async Task <bool> VerifySignatureAsync(string jws, string payload)
        {
            var jwsElements      = jws.Split(".");
            var joseHeaderBase64 = jwsElements[0];
            var signatureBase64  = jwsElements[2];
            var signature        = Base64Url.Decode(signatureBase64);

            var joseHeaderBytes  = Base64Url.Decode(joseHeaderBase64);
            var joseHeaderString = Encoding.UTF8.GetString(joseHeaderBytes);
            var joseHeader       = JsonConvert.DeserializeObject <JoseHeader>(joseHeaderString);

            if (!Uri.TryCreate(joseHeader.JsonWebKeySetUri, UriKind.Absolute, out var jwksUri) ||
                jwksUri != _expectedJwksUri)
            {
                return(false);
            }

            using var httpClient = _httpClientFactory.CreateClient();
            var jwksResponse = await httpClient.GetAsync(_expectedJwksUri);

            var jwksString = await jwksResponse.Content.ReadAsStringAsync();

            var jwks = JsonConvert.DeserializeObject <JsonWebKeySet>(jwksString);
            var key  = jwks.Keys.Single(s => s.KeyId == joseHeader.KeyId);

            var rsaPublicKey = new RSACryptoServiceProvider();

            rsaPublicKey.ImportParameters(
                new RSAParameters {
                Modulus = Base64Url.Decode(key.Modulus), Exponent = Base64Url.Decode(key.Exponent)
            });

            var payloadBase64 = Base64Url.Encode(Encoding.UTF8.GetBytes(payload));
            var securedInput  = $"{joseHeaderBase64}.{payloadBase64}";

            var jwtSettings       = new JwtSettings();
            var jwsAlgorithmValue = jwtSettings.JwsAlgorithmFromHeader(joseHeader.Algorithm);
            var jwsAlgorithm      = jwtSettings.Jws(jwsAlgorithmValue);

            return(jwsAlgorithm.Verify(signature, Encoding.UTF8.GetBytes(securedInput), rsaPublicKey));
        }