.netcore2.1 使用IdentityServer4 生成Token驗證


  每個新技術權限驗證都有一套機制,之前項目WebApi接口權限驗證用的是Owin做為權限驗證,而.netcore權限限制使用的是IdentityServer4,采用JWT的方法驗證token.

  • 首先使用Guget包管理添加IdentityServer4包的引用,如圖

  

  • 生成token方法
/// <summary>
        /// 生成token
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="key">JwtKey</param>
        /// <returns></returns>
        public static string GenerateToken(string userId, string key)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var keyBytes = System.Text.Encoding.Default.GetBytes(key);
            var authTime = DateTime.UtcNow;
            var expireaAt = authTime.AddHours(24);//token過期時間
            var timestamp = TimeStamp.GenerateTimeStamp(authTime);//生成日間戳
            var sign = MyUnity.GetMd5Upper32((userId + "&" + timestamp + "&" + key).ToUpper());
            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Subject = new ClaimsIdentity(new Claim[] {
                 new Claim(JwtClaimTypes.Audience,"api"),
                 new Claim(JwtClaimTypes.Issuer,"hengfeng"),
                 new Claim(JwtClaimTypes.Id,userId),
                 new Claim("timestamp",timestamp),
                 new Claim("sign",sign),
                   }),
                Expires = expireaAt,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(keyBytes),
                SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);
            return tokenString;
        }

 

   

  • 創建JwtTokenFilter過濾器
 public class JwtTokenFilter : ActionFilterAttribute
    {
        private readonly IConfiguration _config;
        public JwtTokenFilter(IConfiguration configuration)
        {
            _config = configuration;
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            try
            {
                var token = context.HttpContext.Request.Headers["token"];
                var tokenHandler = new JwtSecurityTokenHandler();
                var jwtSecurityToken = tokenHandler.ReadJwtToken(token);
                var claims = jwtSecurityToken.Claims;
                var userid = claims.FirstOrDefault(m => m.Type == "id").Value;
                var sign = claims.FirstOrDefault(m => m.Type == "sign").Value;
                var expireaAt = claims.FirstOrDefault(m => m.Type == "exp").Value;
                var key = _config["jwt_key"];  
                var timestamp = claims.FirstOrDefault(m => m.Type == "timestamp").Value;
                var sign_new = MyUnity.GetMd5Upper32((userid + "&" + timestamp + "&" + key).ToUpper());
                if (!sign_new.Equals(sign, StringComparison.InvariantCultureIgnoreCase))
                {
                    context.Result = new JsonResult( "賬號未登錄");
                }
                else
                {
                    var expiresTime = TimeStamp.ConvertIntDateTime(expireaAt);
                    if ((DateTime.Now - expiresTime).Minutes > 0)
                    {
                        context.Result = new JsonResult("賬號Token失效");
                    }
                }
            }
            catch (Exception ex)
            {
                context.Result = new JsonResult(ex.ToString());
            }
        }
    }
  • 在使用控制器中添加 [ServiceFilter(typeof(JwtTokenFilter))] 特性
     // GET: api/Default/5
        [HttpGet("{id}", Name = "Get")]
        [ServiceFilter(typeof(JwtTokenFilter))]
        public string Get(int id)
        {
            return "value";
        }
  • 如果該控制器不需要驗證token,加上允許匿名訪問特性即可
      [HttpPost]
        [AllowAnonymous]
        public void Post([FromBody] string value)
        {

        }

  最后:注意登錄成功后,需要把生成的token返回給前端,前端再一次請求系統其它需要驗證token的接口中,在head中加上token值。

 

用到的加密算法

  /// <summary>
       /// Md5 16位長度
       /// </summary>
       /// <param name="sValue"></param>
       /// <returns></returns>
        public static string GetMd5Upper16(string sValue)  
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string s = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(sValue)), 4, 8);
            s = s.Replace("-", "").ToUpper();
            return s;
        }
        /// <summary>
        ///  Md5 32位長度
        /// </summary>
        /// <param name="sValue"></param>
        /// <returns></returns>
        public static string GetMd5Upper32(string sValue)  
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string s = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(sValue)));
            s = s.Replace("-", "").ToUpper();
            return s;
        }

 生成 十位的時間戳

        /// <summary>
        /// 獲取十位的時間戳
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GenerateTimeStamp(DateTime dt)
        {
            // Default implementation of UNIX time of the current UTC time  
            TimeSpan ts = dt.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt32(ts.TotalSeconds).ToString();
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM