欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.netcore2.1 使用IdentityServer4 生成Token验证

程序员文章站 2022-03-25 20:18:17
每个新技术权限验证都有一套机制,之前项目WebApi接口权限验证用的是Owin做为权限验证,而.netcore权限限制使用的是IdentityServer4,采用JWT的方法验证token. 首先使用Guget包管理添加IdentityServer4包的引用,如图 生成token方法 创建JwtTo ......

  每个新技术权限验证都有一套机制,之前项目webapi接口权限验证用的是owin做为权限验证,而.netcore权限限制使用的是identityserver4,采用jwt的方法验证token.

  • 首先使用guget包管理添加identityserver4包的引用,如图

  .netcore2.1 使用IdentityServer4 生成Token验证

  • 生成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值。

.netcore2.1 使用IdentityServer4 生成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;
        }