public void Encode_Decode(string enc, byte[] alg)
        {
            var writer = new JwtWriter();

            var descriptor = new JweDescriptor(_bobKey, (KeyManagementAlgorithm)alg, (EncryptionAlgorithm)enc)
            {
                Payload = new JwsDescriptor(_signingKey, SignatureAlgorithm.HS256)
                {
                    Payload = new JwtPayload
                    {
                        { "sub", "Alice" }
                    }
                }
            };

            var token = writer.WriteToken(descriptor);

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignatureByDefault(_signingKey)
                         .WithDecryptionKey(_bobKey)
                         .Build();

            var result = Jwt.TryParse(token, policy, out var jwt);

            Assert.True(result);
            Assert.True(jwt.Payload.TryGetClaim("sub", out var sub));
            Assert.Equal("Alice", sub.GetString());
            jwt.Dispose();
        }
        public void BuilderFails()
        {
            var builder = new TokenValidationPolicyBuilder();

            Assert.Throws <ArgumentNullException>(() => builder.AddValidator(null));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.MaximumTokenSizeInBytes(-1));
            Assert.Throws <InvalidOperationException>(() => builder.RequireMetadataConfiguration("jwks_uri", SignatureAlgorithm.HS256));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignature("issuer", (Jwk)null, SignatureAlgorithm.HS256));
            Assert.Throws <InvalidOperationException>(() => builder.RequireSignature("issuer", SymmetricJwk.GenerateKey(128), (SignatureAlgorithm)null));

            Assert.Throws <ArgumentNullException>(() => builder.RequireSignature("issuer", (Jwks)null, SignatureAlgorithm.HS256));
            Assert.Throws <ArgumentException>(() => builder.RequireSignature("issuer", new StaticKeyProvider(new Jwks(SymmetricJwk.GenerateKey(128))), SignatureAlgorithm.None));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignature("issuer", new StaticKeyProvider(new Jwks(SymmetricJwk.GenerateKey(128))), (SignatureAlgorithm)null));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignature("issuer", (StaticKeyProvider)null, SignatureAlgorithm.HS256));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignature(null, new StaticKeyProvider(new Jwks(SymmetricJwk.GenerateKey(128))), SignatureAlgorithm.HS256));
            Assert.Throws <ArgumentNullException>(() => builder.IgnoreSignature(null));
            Assert.Throws <ArgumentNullException>(() => builder.AcceptUnsecureToken(null));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignatureByDefault((IKeyProvider)null));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignatureByDefault((Jwk)null));
            Assert.Throws <InvalidOperationException>(() => builder.RequireSignatureByDefault(SymmetricJwk.GenerateKey(128)));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignatureByDefault(SymmetricJwk.GenerateKey(128), (string)null));
            Assert.Throws <NotSupportedException>(() => builder.RequireSignatureByDefault(SymmetricJwk.GenerateKey(128), ""));
            Assert.Throws <NotSupportedException>(() => builder.RequireSignatureByDefault((Jwk)null, ""));
            Assert.Throws <ArgumentNullException>(() => builder.RequireSignatureByDefault((IList <Jwk>)null));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.EnableLifetimeValidation(clockSkew: -1));
            Assert.Throws <ArgumentNullException>(() => builder.RequireAudience((string)null));
            Assert.Throws <ArgumentNullException>(() => builder.RequireAudience((IEnumerable <string>)null));
            Assert.Throws <ArgumentNullException>(() => builder.DefaultIssuer(null));
            Assert.Throws <ArgumentNullException>(() => builder.EnableTokenReplayValidation(null));
            Assert.Throws <ArgumentNullException>(() => builder.RequireAlgorithm(null));
            Assert.Throws <ArgumentNullException>(() => builder.WithDecryptionKeys((ICollection <IKeyProvider>)null));
        }
Example #3
0
        public void Read()
        {
            var key = new RsaJwk
                      (
                n: "w7Zdfmece8iaB0kiTY8pCtiBtzbptJmP28nSWwtdjRu0f2GFpajvWE4VhfJAjEsOcwYzay7XGN0b-X84BfC8hmCTOj2b2eHT7NsZegFPKRUQzJ9wW8ipn_aDJWMGDuB1XyqT1E7DYqjUCEOD1b4FLpy_xPn6oV_TYOfQ9fZdbE5HGxJUzekuGcOKqOQ8M7wfYHhHHLxGpQVgL0apWuP2gDDOdTtpuld4D2LK1MZK99s9gaSjRHE8JDb1Z4IGhEcEyzkxswVdPndUWzfvWBBWXWxtSUvQGBRkuy1BHOa4sP6FKjWEeeF7gm7UMs2Nm2QUgNZw6xvEDGaLk4KASdIxRQ",
                e: "AQAB"
                      )
            {
                Kid = "1e9gdk7",
                Alg = SignatureAlgorithm.RsaSha256.Utf8Name
            };
            var reader = new JwtReader();

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(key)
                         .Build();

            var result = reader.TryReadToken("eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogImlzcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5NzAsCiAibmFtZSI6ICJKYW5lIERvZSIsCiAiZ2l2ZW5fbmFtZSI6ICJKYW5lIiwKICJmYW1pbHlfbmFtZSI6ICJEb2UiLAogImdlbmRlciI6ICJmZW1hbGUiLAogImJpcnRoZGF0ZSI6ICIwMDAwLTEwLTMxIiwKICJlbWFpbCI6ICJqYW5lZG9lQGV4YW1wbGUuY29tIiwKICJwaWN0dXJlIjogImh0dHA6Ly9leGFtcGxlLmNvbS9qYW5lZG9lL21lLmpwZyIKfQ.rHQjEmBqn9Jre0OLykYNnspA10Qql2rvx4FsD00jwlB0Sym4NzpgvPKsDjn_wMkHxcp6CilPcoKrWHcipR2iAjzLvDNAReF97zoJqq880ZD1bwY82JDauCXELVR9O6_B0w3K-E7yM2macAAgNCUwtik6SjoSUZRcf-O5lygIyLENx882p6MtmwaL1hd6qn5RZOQ0TLrOYu0532g9Exxcm-ChymrB4xLykpDj3lUivJt63eEGGN6DH5K6o33TcxkIjNrCD4XB1CKKumZvCedgHHF3IAK4dVEDSUoGlH9z4pP_eWYNXvqQOjGs-rDaQzUHl6cQQWNiDpWOl_lxXjQEvQ", policy);
            var token  = result.Token.AsIdToken();

            Assert.Equal("http://server.example.com", token.Issuer);
            Assert.Equal("248289761001", token.Subject);
            Assert.Equal("s6BhdRkqt3", token.Audiences.FirstOrDefault());
            Assert.Equal("n-0S6_WzA2Mj", token.Nonce);
            Assert.Equal(EpochTime.ToDateTime(1311281970), token.ExpirationTime);
            Assert.Equal(EpochTime.ToDateTime(1311280970), token.IssuedAt);
            Assert.Equal("Jane Doe", token.Payload["name"]);
            Assert.Equal("Jane", token.GivenName);
            Assert.Equal("Doe", token.FamilyName);
            Assert.Equal("female", token.Gender);
            Assert.Equal("0000-10-31", token.Birthdate);
            Assert.Equal("*****@*****.**", token.Email);
            Assert.Equal("http://example.com/janedoe/me.jpg", token.Picture);
        }
Example #4
0
        public void Encode_Decode(EncryptionAlgorithm enc, KeyManagementAlgorithm alg)
        {
            var writer        = new JwtWriter();
            var encryptionKey = SelectKey(enc.Name, alg.Name);

            var descriptor = new JweDescriptor
            {
                EncryptionKey       = encryptionKey,
                EncryptionAlgorithm = enc,
                Algorithm           = alg,
                Payload             = new JwsDescriptor
                {
                    SigningKey = _signingKey,
                    Algorithm  = SignatureAlgorithm.HmacSha256,
                    Subject    = "Alice"
                }
            };

            var token = writer.WriteToken(descriptor);

            var reader = new JwtReader(encryptionKey);
            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(_signingKey)
                         .Build();

            var result = reader.TryReadToken(token, policy);

            Assert.Equal(TokenValidationStatus.Success, result.Status);
            Assert.Equal("Alice", result.Token.Subject);
        }
Example #5
0
        static void Main()
        {
            // Creates a symmetric key defined for the 'HS256' algorithm
            var signatureKey = new SymmetricJwk("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");

            // Creates a symmetric key for encryption
            var encryptionKey = new SymmetricJwk("R9MyWaEoyiMYViVWo8Fk4T");

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(signatureKey, SignatureAlgorithm.HmacSha256)
                         .RequireAudience("636C69656E745F6964")
                         .RequireIssuer("https://idp.example.com/")
                         .Build();

            var reader = new JwtReader(encryptionKey);
            var result = reader.TryReadToken("eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiQTEyOEtXIn0.f3VIyjZSlzfxTakllbEQeCIU9xSkoqf9duUsbyqTOs8K9EKu_6xcFw.qbmqiA67XDA89YcmsHWwaA.SiqMox7oLg-kIDN0iGifdtX5ILsL5IyziJJp07O-GTx5OFWSsWiB-5Q_GI8CeGBIaEswpfhR9ND9a6YcqKFFT0pTPnw4cI3tcFOcKgjq1ofCZeu4BQkoifH9QuD744MsNVxGekx-rUQQ8OMcnO7q9sHmc4xkQwRDh8GTjd353mRElJMWU_OBswMc4JnMHYHa9cj4u2f9rqKDG1VHIAFai8A1rhfk8Eh7D7MHWQ1CyrN1enYW7veg2adEbr9VH4qG3hCzsOzUyBWx6aJcrwuGHw.T07kRuo-d66j3lPxFzXfQSFeokkInOzofAx3LWh9v-w", policy);

            if (result.Succedeed)
            {
                Console.WriteLine("The token is " + result.Token);
            }
            else
            {
                Console.WriteLine("Failed to read the token. Reason: " + Environment.NewLine + result.Status);
            }
        }
Example #6
0
        static void Main()
        {
            // Creates a symmetric key defined for the 'HS256' algorithm
            var signatureKey = SymmetricJwk.FromBase64Url("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");

            // Creates a symmetric key for encryption
            var decryptionKey = SymmetricJwk.FromBase64Url("R9MyWaEoyiMYViVWo8Fk4T");

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature("https://idp.example.com/", signatureKey, SignatureAlgorithm.HS256)
                         .RequireAudience("636C69656E745F6964")
                         .WithDecryptionKey(decryptionKey)
                         .Build();

            var result = Jwt.TryParse("eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiZWFOTlpaMXBtREFXSWYzYkg3MFg2V3FfbldzUXhuMjFMUngza1daMG5MYyIsImN0eSI6IkpXVCJ9.PU18XXVByiJLE53zkg1m-SzjZXUdRYkl0X20JtsMKXW54RHn3fcK_w.Bu1SPUTuntwvPfwXTj1OhQ.OuCl09TjUMJk80GdY4n5r6HUnH21dWwT1BAbbvPJg75p_AfMvVNmaQ3dahrSmCkuCI5EF34ynE_qUBAuMH9bcplUWS9GDKJfGugEZgkciWORv5RzXvAAokpElpuaiV09SdBmaepi4FAXvTP4axJUWuOXt2MvjnlwbIXlVqUX9Lha1NnsseBLTjfCclhV0pQEKjnncqjuqTcxmqTqAsxZA1v8RJV_FbzBdVBWwQ-qrjYbsrqtsK13XazZEGwAHU7fJT1vlaBdlni6aTQIlwE7JuLA--6hRM9mr7NZ4SlihCFBLjW-DZ2QoQBd6XeFNGKMnNgUP0t6mYihPlmh1eC0BivPaTtCKf4CH6lrq42_17s.ajGQE7r5eAd9z8a-8mmq2g", policy, out var jwt);

            if (result)
            {
                Console.WriteLine("The token is " + jwt);
            }
            else
            {
                Console.WriteLine("Failed to read the token. Reason: " + Environment.NewLine + jwt.Error.Status);
            }

            jwt.Dispose();
        }
Example #7
0
        public void Encode_Decode(string alg)
        {
            var(signingKey, validationKey) = SelectKeys(alg);

            var writer     = new JwtWriter();
            var descriptor = new JwsDescriptor(signingKey, (SignatureAlgorithm)alg)
            {
                Payload = new JwtPayload
                {
                    { "sub", "Alice" }
                }
            };

            var token = writer.WriteTokenString(descriptor);

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignatureByDefault(validationKey, (SignatureAlgorithm)alg)
                         .Build();

            var result = Jwt.TryParse(token, policy, out var jwt);

            Assert.True(result);
            Assert.True(jwt.Payload.TryGetClaim("sub", out var sub));
            Assert.Equal("Alice", sub.GetString());
            jwt.Dispose();
        }
        public void Write_Valid(string token)
        {
            var       descriptor = _tokens.Descriptors[token];
            JwtWriter writer     = new JwtWriter();
            var       value      = writer.WriteToken(descriptor);

            var policy = new TokenValidationPolicyBuilder()
                         .WithDecryptionKeys(_keys.Jwks)
                         .IgnoreSignatureByDefault()
                         .Build();

            var result = Jwt.TryParse(value, policy, out var jwt);

            Assert.True(result);

            if (!(descriptor is JwsDescriptor jwsPayload))
            {
                if (!(descriptor is JweDescriptor jwePayload))
                {
                    throw new Xunit.Sdk.IsNotTypeException(typeof(JwtDescriptor), descriptor);
                }

                jwsPayload = jwePayload.Payload;
            }

            Assert.NotNull(jwsPayload);
            if (jwsPayload.Payload.Count > 0)
            {
                Assert.True(jwt.Payload.TryGetClaim("iat", out var iat));
                Assert.True(jwt.Payload.TryGetClaim("exp", out var exp));
                Assert.True(jwt.Payload.TryGetClaim("iss", out var iss));
                Assert.True(jwt.Payload.TryGetClaim("aud", out var aud));
                Assert.True(jwt.Payload.TryGetClaim("jti", out var jti));
            }
        }
Example #9
0
        static void Main()
        {
            // This sample demonstrates how to validate a token that may come form different issuers.
            // This is common if you have to support multiple Authorization Servers.
            var keyIssuer1        = SymmetricJwk.FromBase64Url("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");
            var keyIssuer2        = SymmetricJwk.FromBase64Url("9dobXhxMWH9PoLsKRdv1qp0bEqJm4YNd8JRaTxes8i4R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");
            var keyIssuer3        = SymmetricJwk.FromBase64Url("lh2TJcMdPyNLhfNp0nYLAFM_R0UEXVoZ9N7ife4ZT-A");
            var policyMultiIssuer = new TokenValidationPolicyBuilder()
                                    .RequireSignature("https://idp1.example.com/", keyIssuer1, SignatureAlgorithm.HS256)
                                    .RequireSignature("https://idp2.example.com/", keyIssuer2, SignatureAlgorithm.HS512)
                                    .RequireSignature("https://idp3.example.com/", keyIssuer3, SignatureAlgorithm.HS256)
                                    .RequireAudience("F6964636C69656E745")
                                    .Build();

            var token = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDAwMDcyMDAsImlhdCI6MjAwMDAwNzIwMCwiaXNzIjoiaHR0cHM6Ly9pZHAzLmV4YW1wbGUuY29tLyIsImF1ZCI6IkY2OTY0NjM2QzY5NjU2RTc0NSJ9.a6RiTht8kyTDL9SZVX9kUye7dJL9YSZxJPbAyaaw3QE";

            // Try to read the token with the different policies
            if (Jwt.TryParse(token, policyMultiIssuer, out var jwt))
            {
                Console.WriteLine($"The token is issued by '{jwt.Payload["iss"].GetString()}':");
                Console.WriteLine(jwt);

                jwt.Dispose();
            }
            else
            {
                Console.WriteLine("Failed to read the token.");
                Console.WriteLine("  Reason: " + jwt.Error.Status);
                jwt.Dispose();
            }
        }
        private static JwsWrapper CreateDescriptor(SignatureAlgorithm algorithm)
        {
            var jwk = algorithm.Category switch
            {
                Cryptography.AlgorithmCategory.None => Jwk.None,
                Cryptography.AlgorithmCategory.EllipticCurve => ECJwk.GeneratePrivateKey(algorithm),
                Cryptography.AlgorithmCategory.Rsa => RsaJwk.GeneratePrivateKey(4096, algorithm),
                Cryptography.AlgorithmCategory.Aes => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.AesGcm => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.Hmac => SymmetricJwk.GenerateKey(algorithm),
                _ => throw new InvalidOperationException()
            };

            var descriptor = new JwsDescriptor(jwk, algorithm)
            {
                Payload = new JwtPayload
                {
                    { JwtClaimNames.Iat, EpochTime.UtcNow },
                    { JwtClaimNames.Exp, EpochTime.UtcNow + EpochTime.OneHour },
                    { JwtClaimNames.Iss, "https://idp.example.com/" },
                    { JwtClaimNames.Aud, "636C69656E745F6964" }
                }
            };
            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature("https://idp.example.com/", jwk, algorithm)
                         .Build();


            var writer = new JwtWriter();

            return(new JwsWrapper(writer.WriteToken(descriptor), algorithm, policy));
        }
    }
        public void Compatible(EncryptionAlgorithm enc, KeyManagementAlgorithm alg)
        {
            var writer = new JwtWriter();

            foreach (var encryptionKey in SelectEncryptionKey(enc.Name.ToString(), alg.Name.ToString()))
            {
                var descriptor = new JweDescriptor(encryptionKey, alg, enc)
                {
                    Payload = new JwsDescriptor(_signingKey, SignatureAlgorithm.HS256)
                    {
                        Payload = new JwtPayload
                        {
                            { "sub", "Alice" }
                        }
                    }
                };

                var token = writer.WriteToken(descriptor);

                var policy = new TokenValidationPolicyBuilder()
                             .RequireSignatureByDefault(_signingKey)
                             .WithDecryptionKeys(_keys.Jwks)
                             .Build();

                var result = Jwt.TryParse(token, policy, out var jwt);
                Assert.True(result);
                Assert.True(jwt.Payload.TryGetClaim("sub", out var sub));
                Assert.Equal("Alice", sub.GetString());
                jwt.Dispose();
            }
        }
Example #12
0
        static void Main()
        {
            // Initializes the shared secret as a symmetric key of 256 bits
            var key = SymmetricJwk.FromBase64Url("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");

            // Defines the validation policy:
            // - Require the issuer "https://idp.example.com/", with the predefined key, with the signature algorithm HS256
            // - Require the audience "636C69656E745F6964"
            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature("https://idp.example.com/", key, SignatureAlgorithm.HS256)
                         .RequireAudience("636C69656E745F6964")
                         .Build();

            // Try to parse the JWT. Its return false
            if (Jwt.TryParse("eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDAwMDcyMDAsImlhdCI6MjAwMDAwNzIwMCwiaXNzIjoiaHR0cHM6Ly9pZHAuZXhhbXBsZS5jb20vIiwiYXVkIjoiNjM2QzY5NjU2RTc0NUY2OTY0In0.YrrT1Ddp1ampsDd2GwYZoTz_bUnLt_h--f16wsWBedk", policy, out Jwt jwt))
            {
                Console.WriteLine("The token is " + jwt);
            }
            else
            {
                Console.WriteLine("Failed to read the token. Error: " + Environment.NewLine + jwt.Error);
            }

            // Do not forget to dispose the Jwt, or you may suffer of GC impacts
            jwt.Dispose();
        }
Example #13
0
        public void Fuzz(string value)
        {
            var policy = new TokenValidationPolicyBuilder()
                         .IgnoreSignatureByDefault()
                         .WithDecryptionKey(key)
                         .Build();
            var parsed = Jwt.TryParse(value, policy, out var jwt);

            Assert.NotNull(jwt);
            jwt.Dispose();
        }
Example #14
0
        /// <summary>
        /// Requires a JWT representing a SECEVENT, verify the presence of the 'events' claim.
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static TokenValidationPolicyBuilder RequireSecEventToken(this TokenValidationPolicyBuilder builder)
        {
            if (builder == null)
            {
                throw new System.ArgumentNullException(nameof(builder));
            }

            builder.RequireClaim(SecEventClaimNames.Events.ToString());

            return(builder);
        }
Example #15
0
 public void ConfigurePolicy(TokenValidationPolicyBuilder builder)
 {
     if (Jwk != null)
     {
         builder.RequireSignature(Issuer, Jwk, SignatureAlgorithm);
     }
     else if (JwksUri != null)
     {
         builder.RequireSignature(Issuer, JwksUri, SignatureAlgorithm);
     }
 }
Example #16
0
        public TokenValidationPolicy BuildPolicy(string audience)
        {
            var builder = new TokenValidationPolicyBuilder();

            builder.RequireAudience(audience)
            .RequireSecEventToken();

            for (int i = 0; i < _registrations.Count; i++)
            {
                var registration = _registrations[i];
                registration.ConfigurePolicy(builder);
            }

            return(builder.Build());
        }
        public void Rfc7516_Decrypt()
        {
            Jwk    encryptionKey = SymmetricJwk.FromBase64Url("GawgguFyGrWKav7AX4VKUg");
            string token         = "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ.AxY8DCtDaGlsbGljb3RoZQ.KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.U0m_YmjN04DJvceFICbCVQ";

            var policy = new TokenValidationPolicyBuilder()
                         .WithDecryptionKey(encryptionKey)
                         .IgnoreSignatureByDefault()
                         .Build();

            var result = Jwt.TryParse(token, policy, out var jwt);

            Assert.True(result);
            Assert.Equal("Live long and prosper.", jwt.Plaintext);
            jwt.Dispose();
        }
Example #18
0
        public void Read()
        {
            var reader = new JwtReader(_keys.Jwks);

            var policy = new TokenValidationPolicyBuilder()
                         .AcceptUnsecureToken()
                         .RequireSecurityEventToken()
                         .Build();
            var result = reader.TryReadToken("eyJ0eXAiOiJzZWNldmVudCtqd3QiLCJhbGciOiJub25lIn0.eyJqdGkiOiI0ZDM1NTllYzY3NTA0YWFiYTY1ZDQwYjAzNjNmYWFkOCIsImlhdCI6MTQ1ODQ5NjQwNCwiaXNzIjoiaHR0cHM6Ly9zY2ltLmV4YW1wbGUuY29tIiwiYXVkIjpbImh0dHBzOi8vc2NpbS5leGFtcGxlLmNvbS9GZWVkcy85OGQ1MjQ2MWZhNWJiYzg3OTU5M2I3NzU0IiwiaHR0cHM6Ly9zY2ltLmV4YW1wbGUuY29tL0ZlZWRzLzVkNzYwNDUxNmIxZDA4NjQxZDc2NzZlZTciXSwiZXZlbnRzIjp7InVybjppZXRmOnBhcmFtczpzY2ltOmV2ZW50OmNyZWF0ZSI6eyJyZWYiOiJodHRwczovL3NjaW0uZXhhbXBsZS5jb20vVXNlcnMvNDRmNjE0MmRmOTZiZDZhYjYxZTc1MjFkOSIsImF0dHJpYnV0ZXMiOlsiaWQiLCJuYW1lIiwidXNlck5hbWUiLCJwYXNzd29yZCIsImVtYWlscyJdfX19.", policy);
            var token  = result.Token.AsSecurityEventToken();
            var events = token.Events;

            Assert.True(events.ContainsKey("urn:ietf:params:scim:event:create"));
            Assert.True(events["urn:ietf:params:scim:event:create"].ContainsKey("ref"));
            Assert.Equal("https://scim.example.com/Users/44f6142df96bd6ab61e7521d9", (string)events["urn:ietf:params:scim:event:create"]["ref"].Value);
        }
Example #19
0
        static void Main()
        {
            // This sample demonstrates how to validate a token that may come form different issuers.
            // This is common if you have to support multiple Authorization Servers.
            var keyIssuer1    = new SymmetricJwk("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");
            var policyIssuer1 = new TokenValidationPolicyBuilder()
                                .RequireSignature(keyIssuer1, SignatureAlgorithm.HmacSha256)
                                .RequireAudience("636C69656E745F6964")
                                .RequireIssuer("https://idp1.example.com/")
                                .Build();

            var keyIssuer2    = new SymmetricJwk("9dobXhxMWH9PoLsKRdv1qp0bEqJm4YNd8JRaTxes8i4");
            var policyIssuer2 = new TokenValidationPolicyBuilder()
                                .RequireSignature(keyIssuer2, SignatureAlgorithm.HmacSha256)
                                .RequireAudience("9656E745F6964636C6")
                                .RequireIssuer("https://idp2.example.com/")
                                .Build();

            var keyIssuer3    = new SymmetricJwk("lh2TJcMdPyNLhfNp0nYLAFM_R0UEXVoZ9N7ife4ZT-A");
            var policyIssuer3 = new TokenValidationPolicyBuilder()
                                .RequireSignature(keyIssuer3, SignatureAlgorithm.HmacSha256)
                                .RequireAudience("F6964636C69656E745")
                                .RequireIssuer("https://idp3.example.com/")
                                .Build();

            var policies = new[] { policyIssuer1, policyIssuer2, policyIssuer3 };

            var reader = new JwtReader();
            var token  = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDAwMDcyMDAsImlhdCI6MjAwMDAwNzIwMCwiaXNzIjoiaHR0cHM6Ly9pZHAzLmV4YW1wbGUuY29tLyIsImF1ZCI6IkY2OTY0NjM2QzY5NjU2RTc0NSJ9.a6RiTht8kyTDL9SZVX9kUye7dJL9YSZxJPbAyaaw3QE";

            for (int i = 0; i < policies.Length; i++)
            {
                // Try to read the token with the different policies
                var result = reader.TryReadToken(token, policies[i]);
                if (result.Succedeed)
                {
                    Console.WriteLine($"The token is issued by '{result.Token.Issuer}':");
                    Console.WriteLine(result.Token);
                    break;
                }

                Console.WriteLine($"Failed to read the token for the issuer '{policies[i].RequiredIssuer}'.");
                Console.WriteLine("  Reason: " + result.Status);
            }
        }
Example #20
0
        private static void Main()
        {
            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(signingKey)
                         .RequireAudience("636C69656E745F6964")
                         .RequireIssuer("https://idp.example.com/")
                         .EnableLifetimeValidation()
                         .Build();

            Console.WriteLine("Starting...");
            _reader.EnableHeaderCaching = false;
            //var sha = new Sha512();
            //Span<byte> dest = new byte[64];
            //var src = new byte[4096];
            while (true)
            {
                //sha.ComputeHash(src, dest);
                _reader.TryReadToken(jwsToken, policy);
            }
        }
Example #21
0
        static void Main()
        {
            var key    = new SymmetricJwk("R9MyWaEoyiMYViVWo8Fk4TUGWiSoaW6U1nOqXri8_XU");
            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(key, SignatureAlgorithm.HmacSha256)
                         .RequireAudience("636C69656E745F6964")
                         .RequireIssuer("https://idp.example.com/")
                         .Build();

            var reader = new JwtReader();
            var result = reader.TryReadToken("eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDAwMDcyMDAsImlhdCI6MjAwMDAwNzIwMCwiaXNzIjoiaHR0cHM6Ly9pZHAuZXhhbXBsZS5jb20vIiwiYXVkIjoiNjM2QzY5NjU2RTc0NUY2OTY0In0.YrrT1Ddp1ampsDd2GwYZoTz_bUnLt_h--f16wsWBedk", policy);

            if (result.Succedeed)
            {
                Console.WriteLine("The token is " + result.Token);
            }
            else
            {
                Console.WriteLine("Failed to read the token. Reason: " + Environment.NewLine + result.Status);
            }
        }
Example #22
0
        public void Write_Binary()
        {
            var data = new byte[256];

            FillData(data);
            var key = RsaJwk.FromBase64Url
                      (
                n: "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1WlUzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDprecbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBIY2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw",
                e: "AQAB",
                d: "VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-rynq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-KyvjT1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ",
                p: "9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEPkrdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM",
                q: "uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-yBhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0",
                dp: "w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuvngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcraHawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs",
                dq: "o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU",
                qi: "eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlCtUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZB9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo",
                alg: KeyManagementAlgorithm.Rsa1_5
                      );

            var descriptor = new BinaryJweDescriptor(key, KeyManagementAlgorithm.Rsa1_5, EncryptionAlgorithm.A128CbcHS256)
            {
                Payload = data
            };

            JwtWriter writer = new JwtWriter();
            var       value  = writer.WriteToken(descriptor);

            Assert.NotNull(value);

            var policy = new TokenValidationPolicyBuilder()
                         .WithDecryptionKey(key)
                         .IgnoreSignatureByDefault()
                         .Build();

            var result = Jwt.TryParse(value, policy, out var jwt);

            Assert.True(result);

            Assert.True(jwt.RawValue.Span.SequenceEqual(data));
        }
        public void Write_Utf8ToEscape()
        {
            var plaintext = "Live long and prosper!€";

            var descriptor = new PlaintextJweDescriptor(RsaKey, KeyManagementAlgorithm.Rsa1_5, EncryptionAlgorithm.A128CbcHS256);

            descriptor.Payload = plaintext;

            JwtWriter writer = new JwtWriter();
            var       value  = writer.WriteToken(descriptor);

            var policy = new TokenValidationPolicyBuilder()
                         .WithDecryptionKey(RsaKey)
                         .IgnoreSignatureByDefault()
                         .Build();

            var result = Jwt.TryParse(value, policy, out var jwt);

            Assert.True(result);

            Assert.Equal(plaintext, jwt.Plaintext);
        }
        private static JweWrapper CreateDescriptor(KeyManagementAlgorithm algorithm, EncryptionAlgorithm encryptionAlgorithm)
        {
            var jwk = algorithm.Category switch
            {
                Cryptography.AlgorithmCategory.None => Jwk.None,
                Cryptography.AlgorithmCategory.EllipticCurve => ECJwk.GeneratePrivateKey(EllipticalCurve.P256, algorithm),
                Cryptography.AlgorithmCategory.Rsa => RsaJwk.GeneratePrivateKey(4096, algorithm),
                Cryptography.AlgorithmCategory.Aes => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.AesGcm => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.Hmac => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.Direct => SymmetricJwk.GenerateKey(encryptionAlgorithm),
                Cryptography.AlgorithmCategory.Direct | Cryptography.AlgorithmCategory.EllipticCurve => ECJwk.GeneratePrivateKey(EllipticalCurve.P256),
                _ => throw new InvalidOperationException(algorithm.Category.ToString())
            };

            var descriptor = new JweDescriptor(jwk, algorithm, encryptionAlgorithm)
            {
                Payload = new JwsDescriptor(Jwk.None, SignatureAlgorithm.None)
                {
                    Payload = new JwtPayload
                    {
                        { JwtClaimNames.Iat, EpochTime.UtcNow },
                        { JwtClaimNames.Exp, EpochTime.UtcNow + EpochTime.OneHour },
                        { JwtClaimNames.Iss, "https://idp.example.com/" },
                        { JwtClaimNames.Aud, "636C69656E745F6964" }
                    }
                }
            };
            var policy = new TokenValidationPolicyBuilder()
                         .AcceptUnsecureToken("https://idp.example.com/")
                         .WithDecryptionKey(jwk)
                         .Build();

            var writer = new JwtWriter();

            return(new JweWrapper(writer.WriteToken(descriptor), algorithm, encryptionAlgorithm, policy));
        }
    }
Example #25
0
        public void Encode_Decode(string alg)
        {
            var(signingKey, validationKey) = SelectKeys(alg);
            var writer     = new JwtWriter();
            var descriptor = new JwsDescriptor
            {
                SigningKey = signingKey,
                Algorithm  = (SignatureAlgorithm)alg,
                Subject    = "Alice"
            };

            var token = writer.WriteToken(descriptor);

            var reader = new JwtReader();
            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(validationKey, (SignatureAlgorithm)alg)
                         .Build();

            var result = reader.TryReadToken(token, policy);

            Assert.Equal(TokenValidationStatus.Success, result.Status);
            Assert.Equal("Alice", result.Token.Subject);
        }
Example #26
0
            public override string Transform(IConsole console, string data)
            {
                console.Verbose($@"Decrypting the JWK...
Password derivation iteration count: {_iterationCount}
Password derivation salt size: {_saltSize} bits");
                var decryptionKey = PasswordBasedJwk.FromPassphrase(_password, _iterationCount, _saltSize);
                var policy        = new TokenValidationPolicyBuilder().WithDecryptionKeys(decryptionKey).IgnoreNestedToken().AcceptUnsecureTokenByDefault().Build();
                Jwt?jwt           = null;

                try
                {
                    if (!Jwt.TryParse(data, policy, out jwt))
                    {
                        throw new InvalidOperationException($"Failed to decrypt the key.\n{jwt.Error!.Status}\n{jwt.Error!.Message}");
                    }

                    console.Verbose("JWK decrypted.");
                    return(jwt.Plaintext);
                }
                finally
                {
                    jwt?.Dispose();
                }
            }
 /// <summary>Add configuration from the OIDC configuration, including issuer validation and signature requirement.</summary>
 public static TokenValidationPolicyBuilder AddOpenIdConfiguration(this TokenValidationPolicyBuilder builder, string metadataAddress, SignatureAlgorithm algorithm)
 {
     return(builder.RequireMetadataConfiguration(metadataAddress, algorithm));
 }
Example #28
0
        private void NewConnectionHandler()
        {
            var server = new TcpListener(ip, port);

            server.Start();

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(SymmetricJwk.FromBase64Url(confWebSocket.JwsKey), SignatureAlgorithm.HmacSha512)
                         .RequireIssuer("Leierkasten Backend")
                         .Build();
            var reader = new JwtReader();

            while (running)
            {
                TcpClient client;
                if (server.Pending())
                {
                    client = server.AcceptTcpClient();
                }
                else
                {
                    Thread.Sleep(100);
                    continue;
                }

                var stream = client.GetStream();
                stream.WriteTimeout = 10;

                while (client.Available < 3)
                {
                    Thread.Sleep(100);
                }

                var bytes = new byte[client.Available];
                stream.Read(bytes, 0, bytes.Length);

                // This is a textual request, decode it
                var request = Encoding.UTF8.GetString(bytes);

                // Check if this is a websocket handshake. If no, skip.
                if (!new Regex("^GET").IsMatch(request))
                {
                    Log.Warn("Denied websocket because client used wrong method.");
                    stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length);
                    continue;
                }

                const string eol  = "\r\n";
                const string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

                // HTML headers are case insensitive
                var match = new Regex("Sec-WebSocket-Key: (.*)", RegexOptions.IgnoreCase).Match(request);
                if (!match.Success)
                {
                    Log.Warn("Sec-WebSocket-Key was not found in request.");
                    Log.Trace("Request was (base64-encoded): " + Convert.ToBase64String(Encoding.ASCII.GetBytes(request)));
                    stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length);
                    continue;
                }

                if (match.Groups.Count != 2)
                {
                    InvalidMatchNumber(match, stream);
                    continue;
                }
                string key             = match.Groups[1].Value.Trim();
                byte[] hashedAcceptKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key + guid));
                string base64AcceptKey = Convert.ToBase64String(hashedAcceptKey);

                Log.Trace("Received Sec-WebSocket-Key: " + key);
                if (Log.IsTraceEnabled)
                {
                    StringBuilder hex = new StringBuilder(hashedAcceptKey.Length * 2);
                    foreach (byte b in hashedAcceptKey)
                    {
                        hex.AppendFormat("{0:x2}", b);
                    }
                    Log.Trace("Hashed Sec-WebSocket-Key: " + hex);
                }

                Log.Trace("Base64 if Sec-WebSocket-Key Hash: " + base64AcceptKey);
                string responseStr = "HTTP/1.1 101 Switching Protocols" + eol
                                     + "Connection: Upgrade" + eol
                                     + "Upgrade: websocket" + eol
                                     + "Sec-WebSocket-Accept: " + base64AcceptKey + eol + eol;
                byte[] response = Encoding.UTF8.GetBytes(responseStr);

                // Get cookie
                match = new Regex("lk-session=([^;\r\n]*)", RegexOptions.IgnoreCase).Match(request);
                if (!match.Success)
                {
                    Log.Warn("Denied websocket because session cookie is missing.");
                    stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length);
                    continue;
                }

                if (match.Groups.Count != 2)
                {
                    InvalidMatchNumber(match, stream);
                    continue;
                }

                // Validate session cookie of user
                var sessionCookie = match.Groups[1].ToString();
                var result        = reader.TryReadToken(sessionCookie, policy);
                if (!result.Succedeed)
                {
                    Log.Warn($"Denied websocket because JWS token could not be validated: {result.ErrorHeader}, {result.ErrorClaim}.");
                    stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length);
                    continue;
                }

                if (result.Token?.Payload == null)
                {
                    Log.Warn("Denied websocket because JWS token payload is empty.");
                    stream.Write(AccessDeniedResponse, 0, AccessDeniedResponse.Length);
                    continue;
                }

                var uid = JsonConvert.DeserializeObject <Dictionary <string, string> >(result.Token.Payload.ToString())["uid"];

                // Send handshake response
                stream.Write(response, 0, response.Length);

                // Start handler for the connection
                var handler = new WebSocketConnection(client, uid);

                if (!ConnectedClients.TryAdd(clientCounter++, handler))
                {
                    handler.Stop();
                }
                else
                {
                    OnClientConnected?.Invoke(this, new ClientConnectedEventArgs(handler));
                }
            }

            server.Stop();
        }