• JWT认证


    前言:

             早期时有涉及过单点登录,一直未有比较清晰直观的理解权限认证这块的东西,本文将从概念到项目中的运用详细讲解(含项目中部分代码)PS:ASE加密解密方法未贴出

    正文:

              JWT 是什么?

    JWT的全称是:Json-web-Token,从字面是上我们不难理解,即web端的一个json类型的token,各方之间的安全json访问对象

    JWT分为三部分

         1.head

             head里面的内容是json串,有两个参数,type:jwt  alg:RSA或者ASE等,这里是代表需要用什么算法进行加密解密

         2Payload 

            payload也是json串,这里用来写一些注册信息,公开以及私有的一些方法

        3Signature 

          Signature 签名,这一步部分是head+payload里的信息整合进行签名,具体是将head的json进行加密、将payload的json进行加密,这两部信息中间用点(.)进行分割,然后再同一将整合的内容进行再次加密,得到的就是最终的token

    JWT使用过程

    client端向认证服务器发起认证授权请求,认证通过后,会向client客户端发送一个token串,客户端拿到token串后再去访问服务器即可

    JWT认证优缺点

    优点:

    认证通过的情况下,资源服务器不必再次做校检token正确与否,只要资源服务器能将token串解密开就可以了,可以减轻认证授权中心的压力

    缺点:

    JWT的token串里的内容多,会很影响性能,安全性能比较弱,一般设置过期的时间不宜太长,而且这个token串在client端是需要存储的

    项目使用案例:

    之前在项目中有开始接触企业微信,需要使用到token做权限验证,即企业微信平台提供一个json串的token,进行加密以及解密操作

    这里企业微信会有两个操作,第一次做一个验证URL的操作,发起一个Get请求,在请求中带入特定的参数,然后使用ASE加密解密算法对参数进行处理,验证通过后,用户发送信息,服务端发起一个Post的请求

    操作与第一步类似,只是在这里会把发送的信息以xml的格式包含在请求head里,此时需要取出然后进行解密再进行拆分,即可获取发送信息,然后再将信息加密后推送至另一端。

    第一次验证操作

                 //Controllers里的方法
    CallBackService callBack = new CallBackService(); msg_signature = HttpContext.Current.Request.QueryString["msg_signature"]; timestamp = HttpContext.Current.Request.QueryString["timestamp"]; nonce = HttpContext.Current.Request.QueryString["nonce"]; echostr = HttpContext.Current.Request.QueryString["echostr"]; return callBack.CallBackCheck(msg_signature, timestamp, nonce, echostr);
    //Service里的方法
    string sVerifyMsgSig = QYVXHttpHelper.ParseUrl("msg_signature"); string sVerifyTimeStamp = QYVXHttpHelper.ParseUrl("timestamp"); string sVerifyNonce = QYVXHttpHelper.ParseUrl("nonce"); QYWeixinHelper.CreateLog("sVerifyMsgSig" + sVerifyMsgSig + "</br>" + "sVerifyTimeStamp:" + sVerifyTimeStamp + "</br>" + "sVerifyNonce:" + sVerifyNonce); //这里注意解码 由于很多验证需要用到密文,解析的时候一定要注意 //直接使用UrlDecode会导致+号丢失 string sVerifyEchoStrtemp = QYVXHttpHelper.ParseUrl("echostr"); string sVerifyEchoStrtemp22 = System.Web.HttpUtility.UrlEncode(sVerifyEchoStrtemp); string sVerifyEchoStr = System.Web.HttpUtility.UrlDecode(sVerifyEchoStrtemp22); QYWeixinHelper.CreateLog("sVerifyEchoStr" + sVerifyEchoStr); string sEchoStr = ""; try { //如果验证通过,把明文作为Get请求的返回值, if (CheckSignature(sToken, sCorpID, sEncodingAESKey, sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr, ref sEchoStr)) { QYWeixinHelper.CreateLog("权限验证通过了"); HttpContext.Current.Response.ContentEncoding = Encoding.UTF8; HttpContext.Current.Response.Write(sEchoStr); return QYVXHttpHelper.ToHttpMsgForWeChat(sEchoStr); } else { return QYVXHttpHelper.ToHttpMsgForWeChat("验证失败,检查CallBackCheck方法"); } } catch (Exception ex) { return QYVXHttpHelper.ToHttpMsgForWeChat(ex.ToString()); }

    第二次发送信息(Post 请求)        //1.验证消息的真实性,并进行解密        //2 根据发送内容不同,指定不同的回复格式 

    //3把回复的数据再次加密,返回
            public static HttpResponseMessage CallBackSend(string sReqMsgSig, string sReqTimeStamp, string sReqNonce, string sReqData)
            {
    string sToken = ReadConfigHelper.ReadBackConfig("Token"); //"swygRd6";
                string sCorpID = ReadConfigHelper.ReadBackConfig("corpid");  // "wx5823bf96d3bd56c7";
                string sEncodingAESKey = ReadConfigHelper.ReadBackConfig("EncodingAESKey"); //"QReQh5qrKlyxNg2NPdH1S6MJSVF8f2LMWI6vrlOV7X6";
    
    
                // Post请求的密文数据
               
                WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
    
    
                string sMsg = "";  // 解析之后的明文
                int ret = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData, ref sMsg);
                //ret==0表示解密验证成功
                if (ret != 0)
                {
                return QYVXHttpHelper.ToHttpMsgForWeChat("CallBackSend验证失败");
                }
    
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(sMsg);
                XmlNode root = doc.FirstChild;
    
    
                #region 回复消息格式 
             
                string MsgType = root["MsgType"].InnerText;
    
                #endregion
    
                string Content = string.Empty;
                string PicUrl = string.Empty;
                string MediaId = string.Empty;
    
                string ResponseResult = string.Empty;
                if (MsgType == "text")
                {
                    QYWeixinHelper.CreateLog("进入文本判断");
    
                    ResponseResult = BackTextXml.ReadTextXml(sMsg);
                }
              //企业需要将发送的信息返回
                // 加密成功,企业需要将加密之后的sEncryptMsg返回
    
                string sEncryptMsg = ""; //xml格式的密文
    
    
                ret = wxcpt.EncryptMsg(ResponseResult, sReqTimeStamp, sReqNonce, ref sEncryptMsg);
                if (ret != 0)
                {
                    return QYVXHttpHelper.ToHttpMsgForWeChat("发送的信息加密失败");
    
                }
    
                //验证成功,再次解密当前的数据,然后发送
    
                QYWeixinHelper.CreateLog("ret=0成功,否则失败" + ret);
    
    
                
                DmUserExEntity ex = new DmUserExEntity();
    
                foreach (var item in root)
                {
                    ex.Reqid = 580005;
                    ex.FromSource = 6;
                    ex.AgentName = root["FromUserName"].InnerText;//消息回复方
                    ex.AgentId = root["AgentID"].InnerText;
          
                    ex.Content = root["Content"].InnerText;
                    
                }
    
     
    
                HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
                HttpContext.Current.Response.Write(sEncryptMsg);
    
                return QYVXHttpHelper.ToHttpMsgForWeChat("OK");
            }
  • 相关阅读:
    软件测试
    数据库中查询json 样式的值的sql语句
    xml转json的方法
    将数据保存本地文件
    Spring 配置 web.xml (防止spring 内存溢出)
    解决maven工程 子工程中的一些配置读取进来的问题
    quartz 的简单使用
    mock 测试 MVC
    sun 证书问题解决
    将文本转换为json的工具类
  • 原文地址:https://www.cnblogs.com/JohnTang/p/16333007.html
Copyright © 2020-2023  润新知