Example #1
0
        public string Encode(Dictionary <string, object> payload, string secretKey)
        {
            DateTime now    = DateTime.Now;
            Base64   base64 = new Base64();


            string tokenHeader = base64.UrlEncode(JsonConvert.SerializeObject(new { alg = "HS256", typ = "JWT" }));

            payload.Add("iat", TimeConverter.ToTimestamp(now)); // 發行時間
            if (!payload.ContainsKey("exp"))
            {
                payload.Add("exp", TimeConverter.ToTimestamp(now.AddHours(3))); // 到期時間
            }

            string tokenPayload   = base64.UrlEncode(JsonConvert.SerializeObject(payload));
            string tokenSignature = new JwsAlgorithm().Hash("HS256", tokenHeader, tokenPayload, secretKey);

            return($"{tokenHeader}.{tokenPayload}.{tokenSignature}");
        }
Example #2
0
        public bool Validate(string token, string secretKey)
        { // 實作自己的檢查方法
            Regex regex = new Regex(@"^[a-zA-Z0-9_\-]+.[a-zA-Z0-9_\-]+.[a-zA-Z0-9_\-]+$");

            if (!regex.IsMatch(token))
            {
                return(false);
            }

            long   now = TimeConverter.ToTimestamp(DateTime.Now);
            string tokenHeader = token.Split('.')[0];
            string tokenPayload = token.Split('.')[1];
            string tokenSignature = token.Split('.')[2];
            Dictionary <string, object> dictHeader, dictPayload;

            try
            {
                Base64 base64      = new Base64();
                string jsonHeader  = base64.UrlDecode(tokenHeader);
                string jsonPayload = base64.UrlDecode(tokenPayload);
                dictHeader  = JsonConvert.DeserializeObject <Dictionary <string, object> >(jsonHeader);
                dictPayload = JsonConvert.DeserializeObject <Dictionary <string, object> >(jsonPayload);
            }
            catch
            {
                return(false);
            }

            string type      = dictHeader.ContainsKey("typ") ? ((string)dictHeader["typ"]).ToUpper() : null;
            string algorithm = dictHeader.ContainsKey("alg") ? ((string)dictHeader["alg"]).ToUpper() : null;

            if (type != null && type != "JWT") // 可以沒有 typ 宣告,但若有則必須為 JWT
            {
                return(false);
            }

            if (algorithm != "HS256") // alg 為必要欄位。本實作只接受 HS256
            {
                return(false);
            }

            /***
             * 與開放規範不同的地方,本次實作將 exp 與 iat 視為必要欄位
             */
            if (dictPayload.ContainsKey("exp") && dictPayload.ContainsKey("iat"))
            {
                long exp = (long)dictPayload["exp"];
                long iat = (long)dictPayload["iat"];

                // 必須滿足 exp > now > nbf > iat
                if (!((exp > iat) && (exp > now)))
                {
                    return(false);
                }
                if (dictPayload.ContainsKey("nbf"))
                {
                    long nbf = (long)dictPayload["nbf"];
                    if (!((exp > nbf) && (nbf > iat) && (now > nbf)))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }


            string signature = new JwsAlgorithm().Hash("HS256", tokenHeader, tokenPayload, secretKey);

            if (signature != tokenSignature)
            {
                return(false);
            }

            return(true);
        }