示例#1
0
        private static SigningCredentials GetSigningCredentials(AsymmetricCipherKeyPair keyPair,
                                                                JsonWebKeySet jsonWebKeySet)
        {
            SigningCredentials signingCredentials = null;

            if (keyPair.Private is RsaPrivateCrtKeyParameters privateRsaParams)
            {
                //For more information about all these RSA private key parameters,
                // please see https://en.wikipedia.org/wiki/RSA_(cryptosystem)
                var rsa = RSA.Create(new RSAParameters
                {
                    Modulus  = privateRsaParams.Modulus.ToByteArray(),       // N (Modulus)
                    P        = privateRsaParams.P.ToByteArray(),             // P is the prime from the key generation : N = P * Q
                    Q        = privateRsaParams.Q.ToByteArray(),             // Q is the prime from the key generation : N = P * Q
                    DP       = privateRsaParams.DP.ToByteArray(),            // DP = D (mod P - 1)
                    DQ       = privateRsaParams.DQ.ToByteArray(),            // DQ = D (mod Q - 1)
                    InverseQ = privateRsaParams.QInv.ToByteArray(),          // InverseQ = Q^(-1) (mod P)
                    D        = privateRsaParams.Exponent.ToByteArray(),      // D is the private exponent
                    Exponent = privateRsaParams.PublicExponent.ToByteArray() // Exponent is the public exponent
                });

                var rsaSecurityKey = new RsaSecurityKey(rsa)
                {
                    KeyId = jsonWebKeySet.Keys.First().Kid
                };
                signingCredentials = new SigningCredentials(rsaSecurityKey,
                                                            SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
            }

            return(signingCredentials);
        }
示例#2
0
        private static JsonWebKeySet GetJsonWebKeySet(RsaKeyParameters keyParameters)
        {
            var e    = Base64UrlEncoder.Encode(keyParameters.Exponent.ToByteArrayUnsigned());
            var n    = Base64UrlEncoder.Encode(keyParameters.Modulus.ToByteArrayUnsigned());
            var dict = new Dictionary <string, string>
            {
                { "e", e },
                { "kty", "RSA" },
                { "n", n }
            };
            var hash       = SHA256.Create();
            var hashBytes  = hash.ComputeHash(System.Text.Encoding.ASCII.GetBytes(JsonSerializer.SerializeToString(dict)));
            var jsonWebKey = new JsonWebKey
            {
                Kid = Base64UrlEncoder.Encode(hashBytes),
                Kty = "RSA",
                E   = e,
                N   = n
            };
            var jsonWebKeySet = new JsonWebKeySet();

            jsonWebKeySet.Keys.Add(jsonWebKey);

            return(jsonWebKeySet);
        }
示例#3
0
        public async Task RefreshMetadataAsync()
        {
            // Get Metadata from endpoint
            var metadataEndpoint = MetadataEndpoint;
            var dataTask         = HttpApiGet(metadataEndpoint);

            // Try to get the JSON metadata object
            JObject json;

            try
            {
                json = JObject.Parse(await dataTask);
            }
            catch (JsonReaderException exception)
            {
                // Fail on invalid JSON
                throw new Exception(
                          $"RefreshMetadataAsync: Metadata address returned invalid JSON object ('{metadataEndpoint}')",
                          exception);
            }

            // Set internal URI properties
            try
            {
                // Preload required data fields
                var jwksEndpoint = new Uri(json[OpenIdProviderMetadataNames.JwksUri].ToString());
                var jwks         = new JsonWebKeySet(await HttpApiGet(jwksEndpoint));

                using (new WriterGuard(_metadata.Lock))
                {
                    _metadata.Jwks                  = jwks;
                    _metadata.JwksEndpoint          = jwksEndpoint;
                    _metadata.Issuer                = json[OpenIdProviderMetadataNames.Issuer].ToString();
                    _metadata.AuthorizationEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.AuthorizationEndpoint].ToString());
                    _metadata.TokenEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.TokenEndpoint].ToString());
                    _metadata.UserInfoEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.UserInfoEndpoint].ToString());
                    _metadata.EndSessionEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.EndSessionEndpoint].ToString());

                    // Check for values
                    if (_metadata.AuthorizationEndpoint == null || _metadata.TokenEndpoint == null ||
                        _metadata.UserInfoEndpoint == null)
                    {
                        throw new Exception("One or more metadata endpoints are missing");
                    }
                }

                // Update refresh time
                _nextCachedRefreshTime = DateTime.Now.Add(_options.MetadataRefreshInterval);
            }
            catch (Exception exception)
            {
                // Fail on invalid URI or metadata
                throw new Exception(
                          $"RefreshMetadataAsync: Metadata address returned incomplete data ('{metadataEndpoint}')", exception);
            }
        }
示例#4
0
        public async Task ShouldUpdateCacheAfterKeyRotation()
        {
            var client = Server.CreateClient();

            // GET JWK
            var request  = new HttpRequestMessage(HttpMethod.Get, Server.JwkEndpoint);
            var response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();
            var jwks = new JsonWebKeySet(await response.Content.ReadAsStringAsync());

            jwks.Keys.Should().HaveCount(1);

            // Force Generate a new one
            request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/renew");

            response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();

            // GET JWK Again - now it needs to have 2 keys.
            request  = new HttpRequestMessage(HttpMethod.Get, Server.JwkEndpoint);
            response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();
            jwks = new JsonWebKeySet(await response.Content.ReadAsStringAsync());
            jwks.Keys.Should().HaveCount(2);
        }
        private void ValidateIdToken(string idTokenJwt, JsonWebKeySet jsonWebKeySet)
        {
            using (_logger.BeginScope("Validating IdToken"))
            {
                var handler  = new JwtSecurityTokenHandler();
                var jwtToken = handler.ReadJwtToken(idTokenJwt);
                var kid      = jwtToken.Header.Kid;
                _logger.LogDebug($"Kid: {kid}");

                var webKey = jsonWebKeySet.Keys.Single(k => k.Kid == kid);

                var e   = Base64Url.Decode(webKey.E);
                var n   = Base64Url.Decode(webKey.N);
                var key = new RsaSecurityKey(new RSAParameters {
                    Exponent = e, Modulus = n
                })
                {
                    KeyId = kid
                };

                var parameters = new TokenValidationParameters
                {
                    ValidIssuer         = _auth.Issuer,
                    ValidAudience       = _auth.ClientId,
                    ValidateAudience    = true,
                    ValidateLifetime    = true,
                    NameClaimType       = "sub",
                    IssuerSigningKey    = key,
                    RequireSignedTokens = true
                };

                var user = handler.ValidateToken(idTokenJwt, parameters, out var _);
            }
        }
示例#6
0
        public JsonWebKeySet GetJsonWebKey(string key)
        {
            var publicKey = key.Replace("\\n", "\n");

            JsonWebKeySet jsonWebKeySet = new JsonWebKeySet();

            using (var textReader = new StringReader(publicKey))
            {
                var pubkeyReader = new PemReader(textReader);
                RsaKeyParameters keyParameters = (RsaKeyParameters)pubkeyReader.ReadObject();
                var e    = Base64UrlEncoder.Encode(keyParameters.Exponent.ToByteArrayUnsigned());
                var n    = Base64UrlEncoder.Encode(keyParameters.Modulus.ToByteArrayUnsigned());
                var dict = new Dictionary <string, string>()
                {
                    { "e", e },
                    { "kty", "RSA" },
                    { "n", n },
                };
                var        hash       = SHA256.Create();
                var        hashBytes  = hash.ComputeHash(System.Text.Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(dict)));
                JsonWebKey jsonWebKey = new JsonWebKey()
                {
                    Kid = Base64UrlEncoder.Encode(hashBytes),
                    Kty = "RSA",
                    E   = e,
                    N   = n,
                };
                jsonWebKeySet.Keys.Add(jsonWebKey);
            }

            return(jsonWebKeySet);
        }
示例#7
0
        private IEnumerable <SecurityKey> GetSigningKeys()
        {
            var httpClient = new HttpClient();

            var identityServerAddress = _configurationManager.Get <string>("IdentityServerAddress");
            var identityServerPath    = _configurationManager.Get("IdentityServerPath", string.Empty);

            var discoveryEndpoint = $"{identityServerAddress}{identityServerPath}/.well-known/openid-configuration";

            logger.Debug($"{nameof(NanoHttp)}.{nameof(GetSigningKeys)}",
                         new LogItem("Event", "Retrieving identity server settings"),
                         new LogItem("Url", discoveryEndpoint));
            var openIdConfigResult = httpClient.GetStringAsync(discoveryEndpoint).Result;
            var openIdConfig       = JsonConvert.DeserializeObject <OpenIdConfig>(openIdConfigResult);

            logger.Debug($"{nameof(NanoHttp)}.{nameof(GetSigningKeys)}",
                         new LogItem("Event", "Retrieving signing keys"),
                         new LogItem("Url", openIdConfig.JwksUri));

            var jwksResult = httpClient.GetStringAsync(openIdConfig.JwksUri).Result;

            try
            {
                var keySet = new JsonWebKeySet(jwksResult);
                return(keySet.GetSigningKeys());
            }
            catch (ArgumentException) { return(null); }
        }
        public void Defaults()
        {
            var           context     = new CompareContext();
            JsonWebKeySet jsonWebKeys = new JsonWebKeySet();

            if (jsonWebKeys.Keys == null)
            {
                context.Diffs.Add("jsonWebKeys.Keys == null");
            }
            else if (jsonWebKeys.Keys.Count != 0)
            {
                context.Diffs.Add("jsonWebKeys.Keys.Count != 0");
            }

            if (jsonWebKeys.AdditionalData == null)
            {
                context.Diffs.Add("jsonWebKeys.AdditionalData == null");
            }
            else if (jsonWebKeys.AdditionalData.Count != 0)
            {
                context.Diffs.Add("jsonWebKeys.AdditionalData.Count != 0");
            }

            TestUtilities.AssertFailIfErrors(context);
        }
示例#9
0
        /// <summary>
        /// Verify if the token that Apple has sent is valid and genuine.
        /// </summary>
        /// <param name="token"></param>
        /// <param name="clientId"></param>
        public static void VerifyAppleIDToken(string token, string clientId)
        {
            var deserializedToken = _tokenHandler.ReadJwtToken(token);
            var claims            = deserializedToken.Claims;

            SecurityKey publicKey;

            var expClaim       = claims.FirstOrDefault(x => x.Type == ClaimConstants.Expiration).Value;
            var expirationTime = DateTimeOffset.FromUnixTimeSeconds(long.Parse(expClaim)).DateTime;

            if (expirationTime < DateTime.UtcNow)
            {
                throw new SecurityTokenExpiredException("Expired token");
            }

            var applePublicKeys = _httpClient.GetAsync("https://appleid.apple.com/auth/keys");
            var keyset          = new JsonWebKeySet(applePublicKeys.Result.Content.ReadAsStringAsync().Result);

            publicKey = keyset.Keys.FirstOrDefault(x => x.Kid == deserializedToken.Header.Kid);

            var validationParameters = new TokenValidationParameters
            {
                ValidIssuer      = "https://appleid.apple.com",
                IssuerSigningKey = publicKey,
                ValidAudience    = clientId
            };

            _tokenHandler.ValidateToken(token, validationParameters, out var _);
        }
        private void ValidateAccessToken(string accessTokenJwt, JsonWebKeySet jsonWebKeySet)
        {
            using (_logger.BeginScope("Validating AccessToken"))
            {
                var handler  = new JwtSecurityTokenHandler();
                var jwtToken = handler.ReadJwtToken(accessTokenJwt);
                var kid      = jwtToken.Header.Kid;
                _logger.LogDebug($"Kid: {kid}");

                var webKey = jsonWebKeySet.Keys.Single(k => k.Kid == kid);

                var certString = webKey.X5c[0];
                _logger.LogDebug($"Cert64: {certString}");
                var certBytes = Base64Url.Decode(certString);
                var cert      = new X509Certificate2(certBytes);
                var key       = new X509SecurityKey(cert);

                var parameters = new TokenValidationParameters
                {
                    ValidIssuer         = _auth.Issuer,
                    ValidAudience       = _auth.Audience,
                    ValidateAudience    = true,
                    ValidateLifetime    = true,
                    AuthenticationType  = "bearer",
                    NameClaimType       = "sub",
                    IssuerSigningKey    = key,
                    RequireSignedTokens = true
                };

                var user = handler.ValidateToken(accessTokenJwt, parameters, out var _);
            }
        }
        private static TokenValidationResult ValidateSignedToken(string serviceJwt, JsonWebKeySet jwksTrustedSigningKeys, bool includeDetails)
        {
            // Now validate the JWT using the signing keys we just discovered
            TokenValidationParameters tokenValidationParams = new TokenValidationParameters
            {
                ValidateAudience  = false,
                ValidateIssuer    = false,
                IssuerSigningKeys = jwksTrustedSigningKeys.GetSigningKeys()
            };
            var jwtHandler     = new JsonWebTokenHandler();
            var validatedToken = jwtHandler.ValidateToken(serviceJwt, tokenValidationParams);

            if (!validatedToken.IsValid)
            {
                throw new ArgumentException("JWT is not valid (signature verification failed)");
            }

            Logger.WriteLine($"JWT signature validation           : True");
            if (includeDetails)
            {
                X509SecurityKey signingKey = (X509SecurityKey)validatedToken.SecurityToken.SigningKey;
                if (signingKey.PublicKey is RSA publicKey)
                {
                    var modulus  = publicKey.ExportParameters(false).Modulus;
                    var exponent = publicKey.ExportParameters(false).Exponent;
                    Logger.WriteLine(37, 80, "    RSA signing key modulus        : ", BitConverter.ToString(modulus).Replace("-", ""));
                    Logger.WriteLine(37, 80, "    RSA signing key exponent       : ", BitConverter.ToString(exponent).Replace("-", ""));
                }
                else
                {
                    Logger.WriteLine($"Unexpected signing key type.  Signing Key Type: {signingKey.PublicKey.GetType()}");
                }
            }
            return(validatedToken);
        }
示例#12
0
        public void When_Passing_JsonWeb_Key_With_Not_Supported_Key_Type_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var jsonWebKeySet = new JsonWebKeySet
            {
                Keys = new List <Dictionary <string, object> >
                {
                    new Dictionary <string, object>
                    {
                        {
                            Constants.JsonWebKeyParameterNames.KeyTypeName,
                            "not_supported"
                        },
                        {
                            Constants.JsonWebKeyParameterNames.KeyIdentifierName,
                            "kid"
                        },
                        {
                            Constants.JsonWebKeyParameterNames.UseName,
                            Constants.UseValues.Encryption
                        }
                    }
                }
            };

            // ACT & ASSERTS
            var ex = Assert.Throws <InvalidOperationException>(() => _jsonWebKeyConverter.ExtractSerializedKeys(jsonWebKeySet));

            Assert.True(ex.Message == ErrorDescriptions.JwkIsInvalid);
        }
        public async Task Jwks_with_ecdsa_should_have_parsable_key(string crv, string alg)
        {
            var key = CryptoHelper.CreateECDsaSecurityKey(crv);

            IdentityServerPipeline pipeline = new IdentityServerPipeline();

            pipeline.OnPostConfigureServices += services =>
            {
                services.AddIdentityServerBuilder()
                .AddSigningCredential(key, alg);
            };
            pipeline.Initialize("/ROOT");

            var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks");

            var json = await result.Content.ReadAsStringAsync();

            var jwks       = new JsonWebKeySet(json);
            var parsedKeys = jwks.GetSigningKeys();

            var matchingKey = parsedKeys.FirstOrDefault(x => x.KeyId == key.KeyId);

            matchingKey.Should().NotBeNull();
            matchingKey.Should().BeOfType <ECDsaSecurityKey>();
        }
示例#14
0
        public async Task WhenTokenIsForDifferentAudienceThenTokenIsNotValid()
        {
            var handler = new JwtSecurityTokenHandler();

            using var rsa = new RSACryptoServiceProvider(2048);
            var jwk           = rsa.CreateSignatureJwk("1", true);
            var keyset        = new JsonWebKeySet().AddKey(rsa.CreateSignatureJwk("1", false));
            var jwksStoreMock = new Mock <IJwksStore>();

            jwksStoreMock.Setup(x => x.GetSigningKey(jwk.Alg, It.IsAny <CancellationToken>()))
            .ReturnsAsync(new SigningCredentials(jwk, jwk.Alg));
            jwksStoreMock.Setup(x => x.GetPublicKeys(It.IsAny <CancellationToken>())).ReturnsAsync(keyset);
            var token = handler.CreateEncodedJwt(
                "http://localhost",
                "test",
                new ClaimsIdentity(new[] { new Claim("sub", "tester"), }),
                DateTime.UtcNow,
                DateTime.UtcNow.AddYears(1),
                DateTime.UtcNow,
                new SigningCredentials(jwk, jwk.Alg));
            var grantedToken = new GrantedToken
            {
                ClientId       = "fake",
                AccessToken    = token,
                ExpiresIn      = 10000,
                CreateDateTime = DateTimeOffset.UtcNow
            };
            var result = await grantedToken.CheckGrantedToken(jwksStoreMock.Object).ConfigureAwait(false);

            Assert.False(result.IsValid);
        }
示例#15
0
        public async Task When_Requesting_JsonWeb_Key_Then_Its_Information_Are_Returned()
        {
            // ARRANGE
            InitializeFakeObjects();
            const string url           = "http://google.be/";
            const string kid           = "kid";
            var          uri           = new Uri(url);
            var          jsonWebKeySet = new JsonWebKeySet();
            var          jsonWebKeys   = new List <JsonWebKey>
            {
                new JsonWebKey
                {
                    Kid = kid
                }
            };
            var json = jsonWebKeySet.SerializeWithJavascript();
            var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(json)
            };
            var handler        = new FakeHttpMessageHandler(httpResponseMessage);
            var httpClientFake = new HttpClient(handler);

            _httpClientFactoryStub.Setup(h => h.GetHttpClient())
            .Returns(httpClientFake);
            _jsonWebKeyConverterStub.Setup(j => j.ExtractSerializedKeys(It.IsAny <JsonWebKeySet>()))
            .Returns(jsonWebKeys);

            // ACT
            var result = await _jsonWebKeyHelper.GetJsonWebKey(kid, uri).ConfigureAwait(false);

            // ASSERTS
            Assert.NotNull(result);
            Assert.True(result.Kid == kid);
        }
示例#16
0
        public void Configure(IApplicationBuilder app)
        {
            //1 . Enable CORS.
            app.UseCors("AllowAll");
            // 4. Use simple identity server.
            app.UseOpenIdApi(_options);
            // 5. Client JWKS endpoint
            app.Map("/jwks_client", a =>
            {
                a.Run(async ctx =>
                {
                    var jwks = new[]
                    {
                        _context.EncryptionKey,
                        _context.SignatureKey
                    };
                    var jsonWebKeySet = new JsonWebKeySet();
                    var publicKeysUsedToValidateSignature = ExtractPublicKeysForSignature(jwks);
                    var publicKeysUsedForClientEncryption = ExtractPrivateKeysForSignature(jwks);
                    var result = new JsonWebKeySet
                    {
                        Keys = new List <Dictionary <string, object> >()
                    };

                    result.Keys.AddRange(publicKeysUsedToValidateSignature);
                    result.Keys.AddRange(publicKeysUsedForClientEncryption);
                    string json = JsonConvert.SerializeObject(result);
                    var data    = Encoding.UTF8.GetBytes(json);
                    ctx.Response.ContentType = "application/json";
                    await ctx.Response.Body.WriteAsync(data, 0, data.Length);
                });
            });
            // 5. Use MVC.
            app.UseMvc();
        }
示例#17
0
        public void ValidateToken_FailsOnLifetime()
        {
            string token  = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiI0YjM2NmY4MDdlMjU0MzlmYmRkOTEwZDc4ZjcwYzlhMSIsInN1YiI6ImZlNmExYmUyLWM5MTEtNDM3OC05Y2MxLTVhY2Y1NjA1Y2ZjMiIsInNjb3BlIjpbImNsb3VkX2NvbnRyb2xsZXIucmVhZCIsImNsb3VkX2NvbnRyb2xsZXJfc2VydmljZV9wZXJtaXNzaW9ucy5yZWFkIiwidGVzdGdyb3VwIiwib3BlbmlkIl0sImNsaWVudF9pZCI6Im15VGVzdEFwcCIsImNpZCI6Im15VGVzdEFwcCIsImF6cCI6Im15VGVzdEFwcCIsImdyYW50X3R5cGUiOiJhdXRob3JpemF0aW9uX2NvZGUiLCJ1c2VyX2lkIjoiZmU2YTFiZTItYzkxMS00Mzc4LTljYzEtNWFjZjU2MDVjZmMyIiwib3JpZ2luIjoidWFhIiwidXNlcl9uYW1lIjoiZGF2ZSIsImVtYWlsIjoiZGF2ZSIsImF1dGhfdGltZSI6MTQ3MzYxNTU0MSwicmV2X3NpZyI6IjEwZDM1NzEyIiwiaWF0IjoxNDczNjI0MjU1LCJleHAiOjE0NzM2Njc0NTUsImlzcyI6Imh0dHBzOi8vdWFhLnN5c3RlbS50ZXN0Y2xvdWQuY29tL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbImNsb3VkX2NvbnRyb2xsZXIiLCJteVRlc3RBcHAiLCJvcGVuaWQiLCJjbG91ZF9jb250cm9sbGVyX3NlcnZpY2VfcGVybWlzc2lvbnMiXX0.Hth_SXpMAyiTf--U75r40qODlSUr60U730IW28K2VidEltW3lN3_CE7HkSjolRGr-DYuWHRvy3i_EwBfj1WTkBaXL373UzPVvNBnat9Gi-vjz07LwmBohk3baG1mmlL8IoGbQwtsmfUPhmO5C6_M4s9wKmTf9XIZPVo_w7zPJadrXfHLfx6iQob7CYpTTix2VBWya29iL7kmD1J1UDT5YRg2J9XT30iFuL6BvPQTkuGnX3ivDuUOSdxM8Z451i0VJmc0LYFBCLJ-Tz6bJ2d0wrtfsbCfuNtxjmGJevcL2jKQbEoiliYj60qNtZdT-ijGUdZjE9caxQ2nOkDkowacpw";
            string keyset = "{ 'keys':[{'kid':'legacy-token-key','alg':'SHA256withRSA','value':'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+7xH35bYBppsn54cBW+\nFlrveTe+3L4xl7ix13XK8eBcCmNOyBhNzhks6toDiRjrgw5QW76cFirVRFIVQkiZ\nsUwDyGOax3q8NOJyBFXiplIUScrx8aI0jkY/Yd6ixAc5yBSBfXThy4EF9T0xCyt4\nxWLYNXMRwe88Y+i+MEoLNXWRbhjJm76LN7rsdIxALbS0vJNWUDALWjtE6FeYX6uU\nL9msAzlCQkdnSvwMmr8Ij2O3IVMxHDJXOZinFqt9zVfXwO11o7ZmiskZnRz1/V0f\nvbUQAadkcDEUt1gk9cbrAhiipg8VWDMsC7VUXuekJZjme5f8oWTwpsgP6cTUzwSS\n6wIDAQAB\n-----END PUBLIC KEY-----','kty':'RSA','use':'sig','n':'AJPu8R9+W2AaabJ+eHAVvhZa73k3vty+MZe4sdd1yvHgXApjTsgYTc4ZLOraA4kY64MOUFu+nBYq1URSFUJImbFMA8hjmsd6vDTicgRV4qZSFEnK8fGiNI5GP2HeosQHOcgUgX104cuBBfU9MQsreMVi2DVzEcHvPGPovjBKCzV1kW4YyZu+ize67HSMQC20tLyTVlAwC1o7ROhXmF+rlC/ZrAM5QkJHZ0r8DJq/CI9jtyFTMRwyVzmYpxarfc1X18DtdaO2ZorJGZ0c9f1dH721EAGnZHAxFLdYJPXG6wIYoqYPFVgzLAu1VF7npCWY5nuX/KFk8KbID+nE1M8Ekus=','e':'AQAB'}]}";
            var    keys   = JsonWebKeySet.Create(keyset);
            var    webKey = keys.Keys[0];


            var parameters = new TokenValidationParameters();
            CloudFoundryOptions options = new CloudFoundryOptions();

            options.TokenKeyResolver          = new CloudFoundryTokenKeyResolver(options);
            options.TokenValidator            = new CloudFoundryTokenValidator(options);
            options.TokenValidationParameters = parameters;
            options.TokenKeyResolver.FixupKey(webKey);
            options.TokenKeyResolver.Resolved["legacy-token-key"] = webKey;

            parameters.ValidateAudience = false;
            parameters.ValidateIssuer   = false;
            parameters.ValidateLifetime = true;


            parameters.IssuerSigningKeyResolver = options.TokenKeyResolver.ResolveSigningKey;

            var result = options.TokenValidator.ValidateToken(token);

            Assert.False(result);
        }
示例#18
0
        public RsaSecurityKey GetRsaSecurityKey(JwtSecurityToken jwtToken, string jwksUrl)
        {
            var tokenSigningKeysJson = _httpClient.GetStringAsync(jwksUrl).Result;
            var jsonWebKeySet        = new JsonWebKeySet(tokenSigningKeysJson);
            var keyToCheck           = jsonWebKeySet.Keys.First(x => x.Kid == jwtToken.Header.Kid);

            if (keyToCheck == null)
            {
                throw new AuthenticationException($@"Could not find the token signing key with id {jwtToken.Header.Kid} from JWKs");
            }

            var rsa = new RSACryptoServiceProvider();

            rsa.ImportParameters(
                new RSAParameters
            {
                Modulus  = ArrayHelper.TrimStart(Base64UrlEncoder.DecodeBytes(keyToCheck.N)),
                Exponent = Base64UrlEncoder.DecodeBytes(keyToCheck.E)
            });
            var signingKey = new RsaSecurityKey(rsa)
            {
                KeyId = keyToCheck.Kid
            };

            return(signingKey);
        }
示例#19
0
        public void X509_read_cer_from_file()
        {
            var bytes = File.ReadAllBytes("test.cer");
            var x509  = new X509Certificate2();

            x509.Import(bytes);

            var x509chain = new X509Chain();

            x509chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
            x509chain.Build(x509);

            var keyset = new JsonWebKeySet
            {
                Keys = new JsonWebKey[]
                {
                    new JsonWebKey
                    {
                        Algorithm         = "RS256",                                   //x509.GetRSAPublicKey().SignatureAlgorithm,
                        KeyType           = x509.GetRSAPublicKey().SignatureAlgorithm, // key type? RSA
                        IntendedUse       = "sig",
                        Cert509Chain      = "",                                        //Convert.ToBase64String(x509.RawData),
                        Exponent          = Convert.ToBase64String(x509.GetRSAPublicKey().ExportParameters(false).Exponent),
                        Modulus           = Convert.ToBase64String(x509.GetRSAPublicKey().ExportParameters(false).Modulus),
                        KeyIdentifier     = x509.Thumbprint,    // ??
                        Cert509Thumbprint = x509.Thumbprint
                    }
                }
            };

            Console.WriteLine(JsonConvert.SerializeObject(keyset));
        }
示例#20
0
        static void Main(string[] args)
        {
            // This part reads the JWKS file and decodes/verifies the token
            JsonWebKeySet             jwks  = JWKSReader.parse("jwks.json");
            JsonWebKey                key   = jwks.Keys[0];
            String                    token = TokenReader.parse("token.txt");
            SecurityToken             validatedToken;
            JwtSecurityTokenHandler   handler = new JwtSecurityTokenHandler();
            TokenValidationParameters validationParameters = new TokenValidationParameters();

            validationParameters.IssuerSigningKey = key;
            validationParameters.ValidateLifetime = false;
            validationParameters.ValidateAudience = false;
            validationParameters.ValidateIssuer   = false;
            handler.ValidateToken(token, validationParameters, out validatedToken);
            Console.WriteLine("The decoded token is:");
            Console.WriteLine(validatedToken);
            Console.WriteLine("\n\n");

            // This part tries to recreate a JsonWebKey from a public key in PEM format.
            JsonWebKey pubKey = PublicKeyReader.parse("ecdsa_public_key.pem");

            Console.WriteLine("Creating a JsonWebKey from public key:");
            Console.WriteLine("x: " + pubKey.X.ToString());
            Console.WriteLine("y: " + pubKey.Y.ToString());
        }
示例#21
0
        public virtual IEnumerable <SecurityKey> ResolveSigningKey(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
        {
            if (Resolved.TryGetValue(kid, out SecurityKey resolved))
            {
                return(new List <SecurityKey> {
                    resolved
                });
            }

            JsonWebKeySet keyset = Task.Run(() => FetchKeySet()).GetAwaiter().GetResult();

            if (keyset != null)
            {
                foreach (JsonWebKey key in keyset.Keys)
                {
                    FixupKey(key);
                    Resolved[key.Kid] = key;
                }
            }

            if (Resolved.TryGetValue(kid, out resolved))
            {
                return(new List <SecurityKey> {
                    resolved
                });
            }

            return(null);
        }
示例#22
0
        /// <summary>
        /// Validate the signature and returns the JWSPayload.
        /// </summary>
        /// <param name="jws"></param>
        /// <param name="jsonWebKeySet"></param>
        /// <returns></returns>
        public JwsPayload ValidateSignature(string jws, JsonWebKeySet jsonWebKeySet)
        {
            if (string.IsNullOrWhiteSpace(jws))
            {
                throw new ArgumentNullException(nameof(jws));
            }

            if (jsonWebKeySet == null)
            {
                throw new ArgumentNullException(nameof(jsonWebKeySet));
            }

            if (jsonWebKeySet.Keys == null)
            {
                throw new ArgumentNullException(nameof(jsonWebKeySet.Keys));
            }

            var jsonWebKeys = _jsonWebKeyConverter.ExtractSerializedKeys(jsonWebKeySet);

            if (!jsonWebKeys.Any())
            {
                return(null);
            }

            var header     = GetHeader(jws);
            var jsonWebKey = jsonWebKeys.FirstOrDefault(s => s.Kid == header.Kid);

            if (jsonWebKey == null)
            {
                return(null);
            }

            return(ValidateSignature(jws, jsonWebKey));
        }
示例#23
0
        public string ValidateToken()
        {
            // get jwks url
            var jwksUrl = GetJwksUrl();

            // get json web keys from its urls
            var jsonWebKeys = new WebClient().DownloadString(jwksUrl);

            // creates a json web keys set
            var jwks       = new JsonWebKeySet(jsonWebKeys);
            var signedKeys = jwks.GetSigningKeys();

            // validate token
            SecurityToken validatedToken;
            var           validationParameters = new TokenValidationParameters
            {
                ValidAudience     = _decodedToken.Audiences.First(),
                IssuerSigningKeys = signedKeys,
                ValidIssuer       = _decodedToken.Issuer
            };

            _tokenHandler.ValidateToken(_token, validationParameters, out validatedToken);
            Console.WriteLine(validatedToken);

            return("ok");
        }
        private void Constructors(
            string testId,
            string json,
            JsonWebKeySet compareTo,
            ExpectedException ee)
        {
            var context = new CompareContext($"{this}.{testId}");

            context.PropertiesToIgnoreWhenComparing.Add(typeof(JsonWebKeySet), new List <string>()
            {
                "SkipUnresolvedJsonWebKeys"
            });
            try
            {
                var jsonWebKeys = new JsonWebKeySet(json);
                var keys        = jsonWebKeys.GetSigningKeys();
                ee.ProcessNoException(context);
                if (compareTo != null)
                {
                    IdentityComparer.AreEqual(jsonWebKeys, compareTo, context);
                }
            }
            catch (Exception ex)
            {
                ee.ProcessException(ex, context.Diffs);
            }

            TestUtilities.AssertFailIfErrors(context);
        }
示例#25
0
        public void When_Passing_JsonWeb_Key_Used_For_The_Signature_With_Ec_Key_But_Which_Doesnt_Contains_XCoordinate_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();
            var jsonWebKey = new Dictionary <string, object>
            {
                {
                    Constants.JsonWebKeyParameterNames.KeyTypeName,
                    Constants.KeyTypeValues.EcName
                },
                {
                    Constants.JsonWebKeyParameterNames.KeyIdentifierName,
                    "kid"
                },
                {
                    Constants.JsonWebKeyParameterNames.UseName,
                    Constants.UseValues.Signature
                }
            };
            var jsonWebKeySet = new JsonWebKeySet
            {
                Keys = new List <Dictionary <string, object> >
                {
                    jsonWebKey
                }
            };
            var json = jsonWebKeySet.SerializeWithJavascript();

            // ACT & ASSERTS
            var ex = Assert.Throws <InvalidOperationException>(() => _jsonWebKeyConverter.ExtractSerializedKeys(jsonWebKeySet));

            Assert.True(ex.Message == ErrorDescriptions.CannotExtractParametersFromJsonWebKey);
        }
        /// <summary>
        /// Retrieves a populated <see cref="OpenIdConnectConfiguration"/> given an address and an <see cref="IDocumentRetriever"/>.
        /// </summary>
        /// <param name="address">address of the jwks uri.</param>
        /// <param name="retriever">the <see cref="IDocumentRetriever"/> to use to read the jwks</param>
        /// <param name="cancel"><see cref="CancellationToken"/>.</param>
        /// <returns>A populated <see cref="OpenIdConnectConfiguration"/> instance.</returns>
        public static async Task <OpenIdConnectConfiguration> GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw LogHelper.LogArgumentNullException(nameof(address));
            }

            if (retriever == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(retriever));
            }

            var doc = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false);

            LogHelper.LogVerbose("IDX21811: Deserializing the string: '{0}' obtained from metadata endpoint into openIdConnectConfiguration object.", doc);
            var jwks = new JsonWebKeySet(doc);
            var openIdConnectConfiguration = new OpenIdConnectConfiguration()
            {
                JsonWebKeySet = jwks,
                JwksUri       = address,
            };

            foreach (var securityKey in jwks.GetSigningKeys())
            {
                openIdConnectConfiguration.SigningKeys.Add(securityKey);
            }

            return(openIdConnectConfiguration);
        }
示例#27
0
        public void TestMethod2()
        {
            List <byte> longBuffer = new List <byte>();

            using (Socket socket = new Socket(SocketType.Stream, ProtocolType.IP)
            {
                ReceiveBufferSize = 8192, LingerState = new LingerOption(false, 0), NoDelay = false
            })
            {
                socket.Connect("172.17.157.74", 9090);
                // Use HTTP 0.9, then we don't need to include a framework for this one little requirement
                socket.Send(Encoding.ASCII.GetBytes("GET /identityService/identity/.well-known/jwks\r\n"));
                Stopwatch w = Stopwatch.StartNew();
                while (socket.Connected && w.ElapsedMilliseconds < 100)
                {
                    if (socket.Available > 0)
                    {
                        byte[] buffer = new byte[socket.Available];
                        socket.Receive(buffer);
                        longBuffer.AddRange(buffer);
                        w.Restart();
                    }
                    else
                    {
                        Thread.Sleep(10);
                    }
                }
            }
            string keys = Encoding.ASCII.GetString(longBuffer.ToArray());

            JsonWebKeySet keyset = new JsonWebKeySet(keys);
        }
示例#28
0
        /*
         * Utilizando o 'Microsoft.Owin.Security.Jwt'
         * faz a validação do Bearer Token.
         */

        public void Configuration(IAppBuilder app)
        {
            using (var http = new HttpClient())
            {
                var keysResponse = http.GetAsync("http://localhost:8080/auth/realms/transurc/protocol/openid-connect/certs").Result;

                var rawKeys = keysResponse.Content.ReadAsStringAsync().Result;

                JsonWebKeySet jsonWebKeySet = JsonConvert.DeserializeObject <JsonWebKeySet>(rawKeys);

                app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
                    AuthenticationMode = AuthenticationMode.Active,
                    Realm = "transurc",


                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        AuthenticationType       = "Bearer",
                        ValidateIssuer           = true,
                        ValidateIssuerSigningKey = true,
                        ValidAudiences           = new string[] { "keycloak-sample-webapp-backend", "keycloak-sample-webapp-frontend" },
                        ValidIssuer       = "http://localhost:8080/auth/realms/transurc",
                        ValidateLifetime  = true,
                        ValidateAudience  = true,
                        IssuerSigningKeys = jsonWebKeySet.GetSigningKeys(),
                    }
                });
            }
        }
        public async Task Jwks_with_two_key_using_different_algs_expect_different_alg_values()
        {
            var ecdsaKey = CryptoHelper.CreateECDsaSecurityKey();
            var rsaKey   = CryptoHelper.CreateRsaSecurityKey();

            IdentityServerPipeline pipeline = new IdentityServerPipeline();

            pipeline.OnPostConfigureServices += services =>
            {
                services.AddIdentityServerBuilder()
                .AddSigningCredential(ecdsaKey, "ES256")
                .AddValidationKey(new SecurityKeyInfo {
                    Key = rsaKey, SigningAlgorithm = "RS256"
                });
            };
            pipeline.Initialize("/ROOT");

            var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks");

            var json = await result.Content.ReadAsStringAsync();

            var jwks = new JsonWebKeySet(json);

            jwks.Keys.Should().Contain(x => x.KeyId == ecdsaKey.KeyId && x.Alg == "ES256");
            jwks.Keys.Should().Contain(x => x.KeyId == rsaKey.KeyId && x.Alg == "RS256");
        }
        public void Constructors(
            string json,
            JsonWebKeySet compareTo,
            JsonSerializerSettings settings,
            ExpectedException ee)
        {
            var context = new CompareContext();

            try
            {
#pragma warning disable CS0618 // Type or member is obsolete
                var jsonWebKeys = new JsonWebKeySet(json, settings);
#pragma warning restore CS0618 // Type or member is obsolete
                var keys = jsonWebKeys.GetSigningKeys();
                ee.ProcessNoException(context);
                if (compareTo != null)
                {
                    IdentityComparer.AreEqual(jsonWebKeys, compareTo, context);
                }
            }
            catch (Exception ex)
            {
                ee.ProcessException(ex, context.Diffs);
            }

            TestUtilities.AssertFailIfErrors(context);
        }
		async Task<JsonWebKeySet> IJwksProvider.RequestJwksAsync() {
			try {
				using( HttpResponseMessage response = await m_httpClient.GetAsync( m_jwksEndpoint ).SafeAsync() ) {
					response.EnsureSuccessStatusCode();
					string jsonResponse = await response.Content.ReadAsStringAsync().SafeAsync();
					var jwks = new JsonWebKeySet( jsonResponse, m_jwksEndpoint );
					return jwks;
				}
			} catch( HttpRequestException e ) {
				throw CreateException( e );
			} catch( JsonWebKeyParseException e ) {
				throw CreateException( e );
			}
		}
示例#32
0
		async Task<JsonWebKeySet> IJwksProvider.RequestJwksAsync() {
			try {
				using( HttpResponseMessage response = await m_httpClient.GetAsync( m_jwksEndpoint ).SafeAsync() ) {
					response.EnsureSuccessStatusCode();
					string jsonResponse = await response.Content.ReadAsStringAsync().SafeAsync();
					var jwks = new JsonWebKeySet( jsonResponse );
					return jwks;
				}
			} catch( HttpRequestException e ) {
				string message = string.Format(
					"Error while looking up JWKS at {0}: {1}",
					m_jwksEndpoint,
					e.Message );
				throw new PublicKeyLookupFailureException( message, e );
			}
		}