• .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();
            }
  • 相关阅读:
    微信小程序中样式问题
    根据后台数据,渲染多个坐标在小程序中
    配置vscode同步大神玺哥的配置
    vue总结
    回文数
    Pytorch的runtime error
    PyTorch图像预处理
    python isinstance()函数
    Java实现weightedUF
    Java Iterator
  • 原文地址:https://www.cnblogs.com/personblog/p/10797200.html
Copyright © 2020-2023  润新知