예제 #1
0
        public static TokenInfo ParseToken(string token, bool validateHmac = true)
        {
            TokenInfo ti = new TokenInfo();

            var parts        = token.Split('.');
            var headerBase64 = parts[0];
            var bodyBase64   = parts[1];
            var signature    = parts[2];

            // parse the header and body into objects
            var headerJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(headerBase64));
            var headerData = JObject.Parse(headerJson);
            var bodyJson   = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(bodyBase64));
            var bodyData   = JObject.Parse(bodyJson);

            // verify algorithm
            var algorithm = (string)headerData["alg"];

            if (algorithm != "HS256")
            {
                throw new NotSupportedException("Only HS256 is supported for this algorithm.");
            }

            if (validateHmac)
            {
                // verify signature
                byte[] bytesToSign = GetBytes(string.Join(".", headerBase64, bodyBase64));
                var    alg         = new HMACSHA256(Convert.FromBase64String(HmacSecret));
                var    hash        = alg.ComputeHash(bytesToSign);
                var    computedSig = JwtUtil.Base64UrlEncode(hash);

                if (computedSig != signature)
                {
                    throw new AuthenticationException("Invalid JWT signature");
                }
            }

            // verify expiration
            var expirationUtc = JwtUtil.ConvertFromUnixTimestamp((long)bodyData["exp"]);

            if (DateTime.UtcNow > expirationUtc)
            {
                throw new AuthenticationException("Token has expired");
            }

            // verify audience
            var jwtAudience = (string)bodyData["aud"];

            if (jwtAudience != JwtManager.AceAudience)
            {
                throw new AuthenticationException($"Invalid audience '{jwtAudience}'.  Expected '{JwtManager.AceAudience}'.");
            }

            ti.Name = (string)bodyData[ClaimTypes.Name] ?? (string)bodyData["unique_name"];

            var roles = bodyData[ClaimTypes.Role] ?? bodyData["role"];

            if (roles != null)
            {
                if (roles.HasValues)
                {
                    ti.Roles = roles.Select(r => (string)r).ToList();
                }
                else
                {
                    ti.Roles = new List <string>()
                    {
                        (string)roles
                    }
                };
            }

            string accountGuid = (string)bodyData[ClaimTypes.NameIdentifier] ?? (string)bodyData["nameid"];

            ti.AccountGuid   = Guid.Parse(accountGuid);
            ti.AccountId     = uint.Parse((string)bodyData["account_id"]);
            ti.IssuingServer = (string)bodyData["issuing_server"];

            return(ti);
        }
예제 #2
0
        public static TokenInfo ParseToken(string token, bool validateHmac = true)
        {
            TokenInfo ti = new TokenInfo();

            var parts        = token.Split('.');
            var headerBase64 = parts[0];
            var bodyBase64   = parts[1];
            var signature    = parts[2];

            // parse the header and body into objects
            var headerJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(headerBase64));
            var headerData = JObject.Parse(headerJson);
            var bodyJson   = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(bodyBase64));
            var bodyData   = JObject.Parse(bodyJson);

            // verify algorithm
            var algorithm = (string)headerData["alg"];

            if (algorithm != "HS256")
            {
                throw new NotSupportedException("Only HS256 is supported for this algorithm.");
            }

            if (validateHmac)
            {
                // verify signature
                byte[] bytesToSign = GetBytes(string.Join(".", headerBase64, bodyBase64));
                var    alg         = new HMACSHA256(Convert.FromBase64String(HmacSecret));
                var    hash        = alg.ComputeHash(bytesToSign);
                var    computedSig = JwtUtil.Base64UrlEncode(hash);

                if (computedSig != signature)
                {
                    throw new AuthenticationException("Invalid JWT signature");
                }
            }

            // verify expiration
            var expirationUtc = JwtUtil.ConvertFromUnixTimestamp((long)bodyData["exp"]);

            if (DateTime.UtcNow > expirationUtc)
            {
                throw new AuthenticationException("Token has expired");
            }

            // verify audience
            var jwtAudience = (string)bodyData["aud"];

            if (jwtAudience != JwtManager.AceAudience)
            {
                throw new AuthenticationException($"Invalid audience '{jwtAudience}'.  Expected '{JwtManager.AceAudience}'.");
            }

            ti.Name = (string)bodyData["account_name"];

            /// TODO: Convert to SecurityLevel instead of AccessLevel
            AccessLevel   thisGuy = AccessLevel.Player;
            List <string> roles   = new List <string>();

            if (Enum.TryParse((string)bodyData["role"], out thisGuy))
            {
                foreach (AccessLevel level in Enum.GetValues(typeof(AccessLevel)))
                {
                    if (thisGuy >= level)
                    {
                        roles.Add(level.ToString());
                    }
                }
            }

            ti.AccountGuid   = Guid.Parse((string)bodyData["account_guid"]);
            ti.IssuingServer = (string)bodyData["issuing_server"];

            return(ti);
        }