Пример #1
0
        /// <summary>
        /// 解析JWT令牌
        /// </summary>
        /// <param name="token">JWT令牌</param>
        /// <param name="claim">Claim名称</param>
        /// <returns>返回指定的Claim值,解析失败返回null</returns>
        public object Parse(string token, JwtClaimNames claim)
        {
            if (string.IsNullOrWhiteSpace(token))
            {
                throw new ArgumentException(nameof(token));
            }

            // 令牌解密
            string jwtStr;

            if (_useAes)
            {
                var jwtBytes = JwtBase64Url.Decode(token);               // 解码
                jwtStr = Encoding.UTF8.GetString(Aes.Decrypt(jwtBytes)); // 解密
            }
            else
            {
                jwtStr = token;
            }

            var parts = jwtStr.Split('.');

            if (parts.Length != 3)
            {
                throw new ArgumentOutOfRangeException(token, "令牌必须由3个由点分隔的部分组成");
            }

            // 解码负载
            var payloadDecode = JwtBase64Url.Decode(parts[1]);
            var json          = Encoding.UTF8.GetString(payloadDecode);
            var claims        = Json.Json.Deserialize <IDictionary <string, object> >(json);

            if (claims != null && claims.TryGetValue(claim.ToStr(), out var result))
            {
                return(result);
            }
            return(null);
        }
Пример #2
0
        /// <summary>
        /// 校验JWT令牌是否有效
        /// </summary>
        /// <param name="token">JWT令牌</param>
        /// <returns>有效返回空字符串,无效返回错误</returns>
        public string Verify(string token)
        {
            string errMsg = "";

            try
            {
                if (string.IsNullOrWhiteSpace(token))
                {
                    throw new ArgumentException(nameof(token));
                }

                // 令牌解密
                string jwtStr;
                if (_useAes)
                {
                    var jwtBytes = JwtBase64Url.Decode(token);               // 解码
                    jwtStr = Encoding.UTF8.GetString(Aes.Decrypt(jwtBytes)); // 解密
                }
                else
                {
                    jwtStr = token;
                }

                var parts = jwtStr.Split('.');
                if (parts.Length != 3)
                {
                    throw new ArgumentOutOfRangeException(token, "令牌必须由3个由点分隔的部分组成");
                }

                // 验证签名
                var header  = parts[0]; // 头
                var payload = parts[1]; // 负载

                // 根据密钥和算法生成签名
                var    key            = Encoding.UTF8.GetBytes(_secret);
                var    signatureData  = $"{header}.{payload}";                 // 生成签名数据
                var    signatureBytes = Encoding.UTF8.GetBytes(signatureData); // 编码成UTF8
                byte[] signatureSha;
                switch (_algorithm)                                            // 进行签名
                {
                case JwtSecurityAlgorithms.HmacSha256: signatureSha = Hash.HSha256(key, signatureBytes); break;

                case JwtSecurityAlgorithms.HmacSha384: signatureSha = Hash.HSha384(key, signatureBytes); break;

                case JwtSecurityAlgorithms.HmacSha512: signatureSha = Hash.HSha512(key, signatureBytes); break;

                default: throw new InvalidOperationException($"不支持的签名算法[{_algorithm}]");
                }
                var signatureStr = JwtBase64Url.Encode(signatureSha);                            // 编码成Base64Url

                if (!signatureStr.Equals(parts[2], StringComparison.InvariantCultureIgnoreCase)) // 比对签名
                {
                    throw new Exception("令牌属于伪造");
                }

                return(errMsg);
            }
            catch (Exception e)
            {
                errMsg = e.Message;
            }

            return(errMsg);
        }