public void ManualWriteNoSig()
        {
            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = JwtConstants.SignatureAlgorithms.None
                },

                Audience = new Uri("http://foo.com"),
                Issuer = "dominick",
                ExpirationTime = 500000,

                Claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, "dominick"),
                    new Claim(ClaimTypes.Email, "*****@*****.**")
                }
            };

            var handler = new JsonWebTokenHandler();

            var token = handler.WriteToken(jwt);
            
            Trace.WriteLine(token);

            Assert.IsTrue(!string.IsNullOrWhiteSpace(token));

            var parts = token.Split('.');
            Assert.IsTrue(parts.Length == 2, "JWT should have excactly 2 parts");
        }
        public override SecurityToken CreateToken(SecurityTokenDescriptor descriptor)
        {
            var jwt = new JsonWebToken();

            if (descriptor.SigningCredentials == null)
            {
                jwt.Header.SignatureAlgorithm = JwtConstants.SignatureAlgorithms.None;
            }
            else
            {
                var algorithm = ParseSigningCredentials(descriptor.SigningCredentials);

                jwt.Header.SigningCredentials = descriptor.SigningCredentials;
                jwt.Header.SignatureAlgorithm = algorithm;
            }

            if (!string.IsNullOrWhiteSpace(descriptor.TokenIssuerName))
            {
                jwt.Issuer = descriptor.TokenIssuerName;
            }

            if (descriptor.Lifetime != null)
            {
                jwt.ExpirationTime = descriptor.Lifetime.Expires.Value.ToEpochTime();
            }

            if (!string.IsNullOrWhiteSpace(descriptor.AppliesToAddress))
            {
                jwt.Audience = new Uri(descriptor.AppliesToAddress);
            }

            if (descriptor.Subject != null)
            {
                foreach (var claim in descriptor.Subject.Claims)
                {
                    jwt.AddClaim(claim.Type, claim.Value);
                }
            }

            return jwt;
        }
        private static string CreateJsonWebToken()
        {
            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = JwtConstants.SignatureAlgorithms.HMACSHA256,
                    SigningCredentials = new HmacSigningCredentials(Constants.IdSrvSymmetricSigningKey)
                },

                Issuer = "http://selfissued.test",
                Audience = new Uri(Constants.Realm),

                Claims = new List<Sys.Claim>
                {
                    new Sys.Claim(Sys.ClaimTypes.Name, "bob"),
                    new Sys.Claim(Sys.ClaimTypes.Email, "*****@*****.**")
                }
            };

            var handler = new JsonWebTokenHandler();
            return handler.WriteToken(jwt);
        }
        public void ManualWriteHmacSha256MissingSigningCredentials()
        {
            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = JwtConstants.SignatureAlgorithms.HMACSHA256
                },

                Audience = new Uri("http://foo.com"),
                Issuer = "dominick",
                ExpirationTime = 500000,

                Claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, "dominick"),
                    new Claim(ClaimTypes.Email, "*****@*****.**")
                }
            };

            var handler = new JsonWebTokenHandler();

            var token = handler.WriteToken(jwt);
        }
        public void ManualWriteUnsupportedSignatureAlgorithm()
        {
            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = "unsupported",
                    SigningCredentials = new HmacSigningCredentials(SymmetricKeyGenerator.Create(48))
                },

                Audience = new Uri("http://foo.com"),
                Issuer = "dominick",
                ExpirationTime = 500000,

                Claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, "dominick"),
                    new Claim(ClaimTypes.Email, "*****@*****.**")
                }
            };

            var handler = new JsonWebTokenHandler();
            var token = handler.WriteToken(jwt);
        }
        public void ManualWriteRoundtripDuplicateClaimTypes()
        {
            var signinKey = SymmetricKeyGenerator.Create(32);

            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = JwtConstants.SignatureAlgorithms.HMACSHA256,
                    SigningCredentials = new HmacSigningCredentials(signinKey)
                },

                Audience = new Uri("http://foo.com"),
                Issuer = "dominick",
                ExpirationTime = 50000000000,
            };

            jwt.AddClaim(ClaimTypes.Name, "dominick");
            jwt.AddClaim(ClaimTypes.Email, "*****@*****.**");
            jwt.AddClaim(ClaimTypes.Role, "bar");
            jwt.AddClaim(ClaimTypes.Role, "foo");


            var handler = new JsonWebTokenHandler();
            var token = handler.WriteToken(jwt);
            Trace.WriteLine(token);

            // token should not be empty
            Assert.IsTrue(!string.IsNullOrWhiteSpace(token));

            // token with signature needs to be 3 parts
            var parts = token.Split('.');
            Assert.IsTrue(parts.Length == 3, "JWT should have excactly 3 parts");

            // signature must be 256 bits
            var sig = Base64Url.Decode(parts[2]);
            Assert.IsTrue(sig.Length == 32, "Signature is not 32 bits");

            var jwtToken = handler.ReadToken(token);


            var config = new SecurityTokenHandlerConfiguration();
            var registry = new WebTokenIssuerNameRegistry();
            registry.AddTrustedIssuer("dominick", "dominick");
            config.IssuerNameRegistry = registry;

            var issuerResolver = new WebTokenIssuerTokenResolver();
            issuerResolver.AddSigningKey("dominick", Convert.ToBase64String(signinKey));
            config.IssuerTokenResolver = issuerResolver;

            config.AudienceRestriction.AllowedAudienceUris.Add(new Uri("http://foo.com"));

            handler.Configuration = config;
            var identity = handler.ValidateToken(jwtToken).First();

            Assert.IsTrue(identity.Claims.Count() == 4);
            Assert.IsTrue(identity.Claims.First().Issuer == "dominick");
        }
        public void ManualWriteHmacSha256KeySizeMismatch()
        {
            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = JwtConstants.SignatureAlgorithms.HMACSHA256,
                    SigningCredentials = new HmacSigningCredentials(SymmetricKeyGenerator.Create(48))
                },

                Audience = new Uri("http://foo.com"),
                Issuer = "dominick",
                ExpirationTime = 500000,

                Claims = new Dictionary<string, string>
                {
                    { ClaimTypes.Name, "dominick" },
                    { ClaimTypes.Email, "*****@*****.**" }
                }
            };

            var handler = new JsonWebTokenHandler();
            var token = handler.WriteToken(jwt);
        }
        protected virtual void VerifySignature(JsonWebToken jwt, SecurityKey signingKey)
        {
            var key = signingKey as InMemorySymmetricSecurityKey;
            if (key == null)
            {
                throw new SecurityTokenValidationException("Unsupported signing key.");
            }

            string verifySignature;
            using (var algorithm = key.GetKeyedHashAlgorithm(ValidateHmacAlgorithm(key.KeySize, jwt.Header.SignatureAlgorithm)))
            {
                verifySignature = Base64Url.Encode(algorithm.ComputeHash(Encoding.UTF8.GetBytes(jwt.UnsignedToken)));
            }

            if (!(ObfuscatingComparer.IsEqual(verifySignature, jwt.Signature)))
            {
                throw new SecurityTokenValidationException("Invalid signature.");
            }
        }
        protected virtual string CreateHeader(JsonWebToken jwt)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);

            using (JsonWriter jsonWriter = new JsonTextWriter(sw))
            {
                jsonWriter.WriteStartObject();

                jsonWriter.WritePropertyName(JwtConstants.Header.Type);
                jsonWriter.WriteValue(jwt.Header.Type);
                jsonWriter.WritePropertyName(JwtConstants.Header.Algorithm);
                jsonWriter.WriteValue(jwt.Header.SignatureAlgorithm);

                jsonWriter.WriteEndObject();
            }

            var json = sb.ToString();
            Debug.WriteLine(json);

            return Base64Url.Encode(Encoding.UTF8.GetBytes(json));
        }
        protected virtual void ReadHeader(string header, JsonWebToken jwt)
        {
            var json = JObject.Load(new JsonTextReader(new StringReader(header)));

            var typ = json[JwtConstants.Header.Type];
            if (typ != null && !string.IsNullOrWhiteSpace(typ.ToString()))
            {
                jwt.Header.Type = typ.ToString();
            }

            var alg = json[JwtConstants.Header.Algorithm];
            if (alg == null || string.IsNullOrEmpty(alg.ToString()))
            {
                throw new SecurityTokenException("Algorithm header is missing.");
            }
            jwt.Header.SignatureAlgorithm = alg.ToString();
        }
        protected virtual void ReadClaims(string claims, JsonWebToken jwt)
        {
            var json = JObject.Load(new JsonTextReader(new StringReader(claims)));

            foreach (var item in json)
            {
                switch (item.Key)
                {
                    case JwtConstants.Claims.Audience:
                        jwt.Audience = new Uri(item.Value.ToString());
                        break;
                    case JwtConstants.Claims.ExpirationTime:
                        jwt.ExpirationTime = long.Parse(item.Value.ToString());
                        break;
                    case JwtConstants.Claims.IssuedAt:
                        jwt.IssuedAt = long.Parse(item.Value.ToString());
                        break;
                    case JwtConstants.Claims.Issuer:
                        jwt.Issuer = item.Value.ToString();
                        break;
                    case JwtConstants.Claims.NotBefore:
                        jwt.NotBefore = long.Parse(item.Value.ToString());
                        break;
                    case JwtConstants.Claims.Principal:
                        jwt.Principal = item.Value.ToString();
                        break;
                    default:
                        jwt.Claims.Add(item.Key, item.Value.ToString());
                        break;
                }
            }
        }
        public override SecurityToken ReadToken(string tokenString)
        {
            if (string.IsNullOrWhiteSpace(tokenString))
            {
                throw new ArgumentNullException("tokenString");
            }

            var jwt = new JsonWebToken();

            var parts = tokenString.Split('.');
            if (parts.Length < 2)
            {
                throw new SecurityTokenException("Malformed token");
            }

            var encodedHeader = parts[0];
            var encodedClaims = parts[1];

            ReadHeader(Encoding.UTF8.GetString(Base64Url.Decode(encodedHeader)), jwt);

            string signature = string.Empty;
            if (jwt.Header.SignatureAlgorithm != JwtConstants.SignatureAlgorithms.None)
            {
                if (parts.Length != 3)
                {
                    throw new SecurityTokenException("Signature is missing");
                }

                signature = parts[2];
            }

            jwt.UnsignedToken = string.Format("{0}.{1}", encodedHeader, encodedClaims);
            jwt.Signature = signature;

            ReadClaims(Encoding.UTF8.GetString(Base64Url.Decode(encodedClaims)), jwt);

            return jwt;
        }
 protected virtual void AddUserClaims(JsonWebToken jwt, JsonTextWriter writer)
 {
     foreach (var claim in jwt.Claims)
     {
         writer.WritePropertyName(claim.Key);
         writer.WriteValue(claim.Value);
     }
 }
        protected virtual void AddReservedClaims(JsonWebToken jwt, JsonTextWriter writer)
        {
            // exp
            if (jwt.ExpirationTime.HasValue)
            {
                writer.WritePropertyName(JwtConstants.Claims.ExpirationTime);
                writer.WriteValue(jwt.ExpirationTime.Value);
            }

            // nbf
            if (jwt.NotBefore.HasValue)
            {
                writer.WritePropertyName(JwtConstants.Claims.NotBefore);
                writer.WriteValue(jwt.NotBefore.Value);
            }

            // iat
            if (jwt.IssuedAt.HasValue)
            {
                writer.WritePropertyName(JwtConstants.Claims.IssuedAt);
                writer.WriteValue(jwt.IssuedAt.Value);
            }

            // iss
            if (!string.IsNullOrWhiteSpace(jwt.Issuer))
            {
                writer.WritePropertyName(JwtConstants.Claims.Issuer);
                writer.WriteValue(jwt.Issuer);
            }

            // aud
            if (jwt.Audience != null)
            {
                writer.WritePropertyName(JwtConstants.Claims.Audience);
                writer.WriteValue(jwt.Audience.AbsoluteUri);
            }

            // prn
            if (!string.IsNullOrWhiteSpace(jwt.Principal))
            {
                writer.WritePropertyName(JwtConstants.Claims.Principal);
                writer.WriteValue(jwt.Principal);
            }

            // jti
            if (!string.IsNullOrWhiteSpace(jwt.JwtId))
            {
                writer.WritePropertyName(JwtConstants.Claims.Id);
                writer.WriteValue(jwt.JwtId);
            }
        }
        protected virtual string CreateClaimSet(JsonWebToken jwt)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);

            using (var jsonWriter = new JsonTextWriter(sw))
            {
                jsonWriter.WriteStartObject();

                AddReservedClaims(jwt, jsonWriter);
                AddUserClaims(jwt, jsonWriter);

                jsonWriter.WriteEndObject();
            }

            var json = sb.ToString();
            Debug.WriteLine(json);

            return Base64Url.Encode(Encoding.UTF8.GetBytes(json));
        }
        protected virtual ClaimsIdentity CreateClaimsIdentity(JsonWebToken jwt)
        {
            var claims = new List<Claim>();

            foreach (var item in jwt.Claims)
            {
                if (item.Value.Contains(','))
                {
                    var items = item.Value.Split(',');
                    foreach (var part in items)
                    {
                        claims.Add(new Claim(item.Key, part, ClaimValueTypes.String, jwt.Issuer));
                    }
                }
                else
                {
                    claims.Add(new Claim(item.Key, item.Value, ClaimValueTypes.String, jwt.Issuer));
                }
            }

            //var claims = new List<Claim>(
            //    from c in jwt.Claims
            //    select new Claim(c.Type, c.Value, c.ValueType, jwt.Issuer));

            if (!string.IsNullOrWhiteSpace(jwt.Principal))
            {
                claims.Add(new Claim("prn", jwt.Principal, ClaimValueTypes.String, jwt.Issuer));
            }

            if (jwt.IssuedAt.HasValue)
            {
                claims.Add(new Claim("iat", jwt.IssuedAt.Value.ToString(), ClaimValueTypes.String, jwt.Issuer));
            }

            return new ClaimsIdentity(claims, "JWT");
        }
        public void ManualWriteHmacSha256ValidSigningCredentials()
        {
            var jwt = new JsonWebToken
            {
                Header = new JwtHeader
                {
                    SignatureAlgorithm = JwtConstants.SignatureAlgorithms.HMACSHA256,
                    SigningCredentials = new HmacSigningCredentials(SymmetricKeyGenerator.Create(32))
                },

                Audience = new Uri("http://foo.com"),
                Issuer = "dominick",
                ExpirationTime = 500000,

                Claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, "dominick"),
                    new Claim(ClaimTypes.Email, "*****@*****.**")
                }
            };

            var handler = new JsonWebTokenHandler();
            var token = handler.WriteToken(jwt);
            Trace.WriteLine(token);

            // token should not be empty
            Assert.IsTrue(!string.IsNullOrWhiteSpace(token));

            // token with signature needs to be 3 parts
            var parts = token.Split('.');
            Assert.IsTrue(parts.Length == 3, "JWT should have excactly 3 parts");

            // signature must be 256 bits
            var sig = Base64Url.Decode(parts[2]);
            Assert.IsTrue(sig.Length == 32, "Signature is not 32 bits");
        }
        protected virtual ClaimsIdentity CreateClaimsIdentity(JsonWebToken jwt)
        {
            var claims = new List<Claim>(
                from c in jwt.Claims
                select new Claim(c.ClaimType, c.Value, c.ValueType, jwt.Issuer));

            if (!string.IsNullOrWhiteSpace(jwt.Principal))
            {
                claims.Add(new Claim("prn", jwt.Principal, ClaimValueTypes.String, jwt.Issuer));
            }

            if (jwt.IssuedAt.HasValue)
            {
                claims.Add(new Claim("iat", jwt.IssuedAt.Value.ToString(), ClaimValueTypes.String, jwt.Issuer));
            }

            return new ClaimsIdentity(claims, "JWT");
        }