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); }
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); }
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); } }
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 _); } }
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); }
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); }
/// <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); }
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>(); }
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); }
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); }
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(); }
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); }
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); }
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)); }
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()); }
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); }
/// <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)); }
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); }
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); }
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); }
/* * 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 ); } }
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 ); } }