Пример #1
0
        /// <summary>
        /// Validation logic for registered claim: JWT ID.
        /// Successful if claim is present and resolves to true when passed through the provided validator.
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public bool Check(JObject claims, ClaimsCheckerVariables variables)
        {
            var jsonJti = claims[RegisteredClaimNames.JwtId];
            if (jsonJti == null) return false;

            return JwtIdValidator(jsonJti.ToString());
        }
Пример #2
0
        /// <summary>
        /// Validation logic for registered claim: Not Before.
        /// Successful if claim is present and current time is at or after the claim value, using leeway period if provided.
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public bool Check(JObject claims, ClaimsCheckerVariables variables)
        {
            var jsonNotBefore = claims[RegisteredClaimNames.NotBefore];
            if (jsonNotBefore == null) return false;

            return jsonNotBefore.ToObject<int>() <= UnixTimeConvert.FromDateTime(DateTime.UtcNow + Leeway);
        }
Пример #3
0
        /// <summary>
        /// Validation logic for registered claim: Subject.
        /// Successful if the claim is not present or the Subject property value in the checker variables equals to the claim value.
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public bool Check(JObject claims, ClaimsCheckerVariables variables)
        {
            var jsonSubject = claims[RegisteredClaimNames.Subject];
            if (jsonSubject == null) return true;
            if (string.IsNullOrEmpty(variables.Subject)) return false;

            return jsonSubject.ToString() == variables.Subject;
        }
Пример #4
0
        /// <summary>
        /// Validation logic for AuthorizeAttribute 'User' claim.
        /// Successful if the Users property is not set in the checker variables or Users property values contain the claim value.
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public bool Check(JObject claims, ClaimsCheckerVariables variables)
        {
            if (string.IsNullOrEmpty(variables.Users)) return true;
            var users = variables.Users.Split(',').Select(Q => Q.Trim()).Where(Q => !string.IsNullOrEmpty(Q)).ToList();
            if (!users.Any()) throw new Exception("No Users can be inferred from the AuthorizeAttribute property value.");

            var jsonUser = claims[this.ClaimName];
            if (jsonUser == null) return false;
            var user = jsonUser.ToString().Trim();

            return users.Where(Q => Q.Equals(user, StringComparison.InvariantCultureIgnoreCase)).Any();
        }
Пример #5
0
        /// <summary>
        /// Validation logic for registered claim: Audience.
        /// Successful if the claim is not present or the claim values contain the Audience property value in the checker variables.
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public bool Check(JObject claims, ClaimsCheckerVariables variables)
        {
            //https://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#rfc.section.4.1.3
            //4.1.3. "aud" (Audience) Claim
            //Each principal intended to process the JWT MUST identify itself with a value in the audience claim.
            //If the principal processing the claim does not identify itself with a value in the aud claim
            //when this claim is present, then the JWT MUST be rejected. Use of this claim is OPTIONAL.

            //So, basically it's like a reverse Role.
            var jsonAudience = claims[RegisteredClaimNames.Audience];
            if (jsonAudience == null) return true;
            if (string.IsNullOrEmpty(variables.Audience)) return false;

            var audiences = jsonAudience.ToObject<List<string>>();
            return audiences.Where(Q => Q == variables.Audience).Any();
        }
Пример #6
0
        public void NoClaims()
        {
            var jwtCodec = new JwtCodec(new JwtConfig
            {
                KeyConfig = new KeyConfig
                {
                    Value = new byte[] { 237, 77, 131, 121, 90, 110, 35, 231, 70, 26, 39, 55, 158, 159, 179, 231 }
                },
                Signer = new HS256Signer()
            });

            var token = jwtCodec.Encode(new { UserId = 1, Username = "******" });

            var variables = new ClaimsCheckerVariables();
            variables.Roles = "Admin, Customer";
            var success = jwtCodec.Decode(token, new List<IClaimsChecker> { new RoleChecker() }, variables);
            Assert.False(success);
        }
Пример #7
0
        public void Fail2()
        {
            var jwtCodec = new JwtCodec(new JwtConfig
            {
                KeyConfig = new KeyConfig
                {
                    Value = new byte[] { 237, 77, 131, 121, 90, 110, 35, 231, 70, 26, 39, 55, 158, 159, 179, 231 }
                },
                Signer = new HS256Signer()
            });

            var token = jwtCodec.Encode(new { UserId = 1, Username = "******" },
                Audience: new List<string> { "UserPanel", "ShoppingCart", "CustomerService" });

            var variables = new ClaimsCheckerVariables();
            variables.Audience = null;
            var success = jwtCodec.Decode(token, new List<IClaimsChecker> { new AudienceChecker() }, variables);
            Assert.False(success);
        }
Пример #8
0
        /// <summary>
        /// Validates a JWT using the helper configuration. 
        /// If successful, run claims check against the token using Roles and checker variables.
        /// </summary>
        /// <param name="token"></param>
        /// <param name="claimsCheckers"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public bool Decode(string token, IEnumerable<IClaimsChecker> claimsCheckers, ClaimsCheckerVariables variables)
        {
            if (!Decode(token)) return false;

            if (claimsCheckers == null) return true;
            if (!claimsCheckers.Any()) return true;

            try
            {
                var jwt = JwtObject.Parse(token);
                var claims = JObject.Parse(jwt.ClaimsAsJson());

                foreach (var checker in claimsCheckers)
                {
                    if (!checker.Check(claims, variables)) return false;
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Пример #9
0
 /// <summary>
 /// Validation logic for registered claim: Issued At.
 /// Successful if claim is present.
 /// </summary>
 /// <param name="claims"></param>
 /// <param name="variables"></param>
 /// <returns></returns>
 public bool Check(JObject claims, ClaimsCheckerVariables variables)
 {
     var jsonIssuedAt = claims[RegisteredClaimNames.IssuedAt];
     return (jsonIssuedAt != null);
 }
Пример #10
0
        public void Sample()
        {
            var jwtConfig = new JwtConfig
            {
                KeyConfig = new KeyConfig
                {
                    Value = new byte[] { 237, 77, 131, 121, 90, 110, 35, 231, 70, 26, 39, 55, 158, 159, 179, 231 }
                },
                Signer = new HS256Signer()
            };

            var jwtCodec = new JwtCodec(jwtConfig);

            var claims = new
            {
                UserId = 1,
                Username = "******",
                Role = "Admin"
            };

            string token1 = jwtCodec.Encode(claims);
            //eyJVc2VySWQiOjEsIlVzZXJuYW1lIjoiamFja2FudG9ubyIsIlJvbGUiOiJBZG1pbiJ9.yCY897l0Qt4pNWAMkLebcwjygiqbkQcFMfNW+BZjCUo=
            output.WriteLine(token1);

            bool isValid = jwtCodec.Decode(token1);
            //True
            output.WriteLine(isValid.ToString());

            var now = new DateTime(2015, 11, 23, 14, 0, 0, DateTimeKind.Utc);
            var token2 = jwtCodec.Encode(claims,
                            Issuer: "accelist.com",
                            Subject: "Authentication",
                            Audience: new List<string> { "EmployeePortal", "SecurityCenter" },
                            ExpirationTime: now.AddHours(12),
                            NotBefore: now,
                            IssuedAt: now,
                            JwtId: Guid.Parse("2628850a-e1a9-4897-bf78-355fa5367ca1").ToString()
                        );
            //eyJVc2VySWQiOjEsIlVzZXJuYW1lIjoiamFja2FudG9ubyIsIlJvbGUiOiJBZG1pbiIsImlzcyI6ImFjY2VsaXN0LmNvbSIsInN1YiI6IkF1dGhlbnRpY2F0aW9uIiwiYXVkIjpbIkVtcGxveWVlUG9ydGFsIiwiU2VjdXJpdHlDZW50ZXIiXSwiZXhwIjoxNDQ4MzMwNDAwLCJuYmYiOjE0NDgyODcyMDAsImlhdCI6MTQ0ODI4NzIwMCwianRpIjoiMjYyODg1MGEtZTFhOS00ODk3LWJmNzgtMzU1ZmE1MzY3Y2ExIn0=.d/ON3EdLGOC0VPcKwiLE15WZKoM9Mwx+3P2QQIhSP8U=
            output.WriteLine(token2);

            /// Validation logic for registered claim: Issuer.
            /// Successful if the Issuer property value equals the claim or claim is not provided.
            var issChecker = new IssuerChecker();
            /// Validation logic for registered claim: Subject.
            /// Successful if the Subject property value equals the claim or claim is not provided.
            var subChecker = new SubjectChecker();
            /// Validation logic for registered claim: Audience.
            /// Successful if the claim is not present or the Audience property value is in the said claim.
            var audChecker = new AudienceChecker();

            var leeway = new TimeSpan(0, 5, 0);
            /// Validation logic for registered claim: Expiration Time.
            /// Successful if claim exists and current time is at or before the said claim, using leeway period if provided.
            var expChecker = new ExpirationTimeChecker(leeway);
            /// Authorization logic for registered claim: Not Before.
            /// Successful if claim exists and current time is at or after the said claim, using leeway period if provided.
            var nbfChecker = new NotBeforeChecker(leeway);
            /// Authorization logic for registered claim: Issued At.
            /// Successful if claim exists.
            var iatChecker = new IssuedAtChecker();

            /// Validation logic for registered claim: JWT ID.
            /// Successful if claims exist and resolves to true when passed through the validator.
            Func<string, bool> jtiValidator = (jti) =>
            {
                return true;
            };
            var jtiChecker = new JwtIdChecker(jtiValidator);

            /// Validation logic for AuthorizeAttribute 'Role' claim.
            /// Successful if the Roles property is not set or the claim is in the Roles property value.
            var roleChecker = new RoleChecker("Role");
            /// Validation logic for AuthorizeAttribute 'User' claim.
            /// Successful if the User property is not set or the claim is in the Users property value.
            var userChecker = new UserChecker("Username");

            var claimsCheckers = new List<IClaimsChecker> { issChecker, subChecker, audChecker, expChecker, nbfChecker, iatChecker, jtiChecker, roleChecker, userChecker };

            var variables = new ClaimsCheckerVariables
            {
                Issuer = "accelist.com",
                Subject = "Administration",
                Roles = "Admin",
                Audience = "EmployeePortal",
                Users = "jackantono, ryanelian",
            };

            jwtCodec.Decode(token2, claimsCheckers, variables);

            var jwtObj = JwtObject.Parse(token2);
            var extractClaims = jwtObj.ClaimsAsObject<ClaimsTest>();
            output.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(extractClaims, Newtonsoft.Json.Formatting.Indented));
        }