Example #1
0
        /// <summary>
        /// 核心执行 过程的  验签和解密
        /// </summary>
        /// <param name="recXml">消息内容</param>
        /// <param name="signature">微信加密签名</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonce">随机数</param>
        /// <returns>验证结果及相应的消息内容体 (如果加密模式,返回的是解密后的明文)</returns>
        private Resp <string> PrepareExecute(string recXml, string signature,
                                             string timestamp, string nonce)
        {
            if (string.IsNullOrEmpty(recXml))
            {
                return(new Resp <string>().WithResp(RespTypes.ObjectNull, "接收的消息体为空!"));
            }

            var resCheck = WXChatHelper.CheckSignature(ApiConfig.Token, signature, timestamp, nonce);

            if (!resCheck.IsSuccess())
            {
                return(new Resp <string>().WithResp(resCheck));// resCheck.ConvertToResult<string>();
            }
            if (ApiConfig.SecurityType == WXSecurityType.None)
            {
                return(new Resp <string>(recXml));
            }

            var dirs = WXChatHelper.ChangXmlToDir(recXml, out XmlDocument xmlDoc);

            if (dirs == null || !dirs.TryGetValue("Encrypt", out var encryStr) ||
                string.IsNullOrEmpty(encryStr))
            {
                return(new Resp <string>().WithResp(RespTypes.ObjectNull, "加密消息为空"));
            }

            var recMsgXml = Cryptography.WXAesDecrypt(encryStr, ApiConfig.EncodingAesKey);

            return(new Resp <string>(recMsgXml));
        }
Example #2
0
        /// <summary>
        /// 消息处理入口
        /// </summary>
        /// <param name="contentXml">内容信息</param>
        /// <param name="signature">签名信息</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonce">随机字符创</param>
        /// <param name="echostr">验证服务器参数,如果存在则只进行签名验证,并将在结果data中返回</param>
        /// <returns>消息结果,Data为响应微信数据,如果出错Message为错误信息</returns>
        public Resp <string> Process(string contentXml, string signature, string timestamp, string nonce,
                                     string echostr)
        {
            // 一.  检查是否是服务器验证
            if (!string.IsNullOrEmpty(echostr))
            {
                return(CheckServerValid(signature, timestamp, nonce, echostr));
            }

            // 二.  正常消息处理
            var checkRes = PrepareExecute(contentXml, signature, timestamp, nonce);

            if (!checkRes.IsSuccess())
            {
                return(new Resp <string>().WithResp(checkRes)); //checkRes.ConvertToResult<string>();
            }
            var contextRes = Execute(checkRes.data);

            if (!contextRes.IsSuccess())
            {
                return(new Resp <string>().WithResp(contextRes));// contextRes.ConvertToResult<string>();
            }
            var resultString = contextRes.data.ReplyMsg.ToReplyXml();

            if (ApiConfig.SecurityType != WXSecurityType.None &&
                !string.IsNullOrEmpty(contextRes.data.ReplyMsg.MsgType))
            {
                return(WXChatHelper.EncryptMsg(resultString, ApiConfig));
            }
            return(new Resp <string>(resultString));
        }
Example #3
0
        /// <summary>
        /// 核心执行方法 过程中的 委托方代码执行
        /// </summary>
        /// <param name="recMsgXml">传入消息的xml</param>
        /// <returns></returns>
        protected virtual Resp <WXChatContext> Execute(string recMsgXml)
        {
            var recMsgDirs = WXChatHelper.ChangXmlToDir(recMsgXml, out XmlDocument xmlDoc);

            recMsgDirs.TryGetValue("MsgType", out var msgType);// recMsgDirs["MsgType"].ToLower();
            string eventName = null;

            if (msgType == "event")
            {
                if (!recMsgDirs.TryGetValue("Event", out eventName))
                {
                    return(new Resp <WXChatContext>().WithResp(RespTypes.ParaError, "事件消息数据中未发现 事件类型(Event)字段!"));
                }
            }

            var processor = GetBasicMsgProcessor(msgType, eventName);

            if (!(processor?.CanExecute).HasValue)
            {
                processor = GetCustomProcessor(msgType, eventName, recMsgDirs);
                if (!(processor?.CanExecute).HasValue)
                {
                    processor = GetRegProcessor(msgType, eventName);
                }
            }

            var context = processor != null && processor.CanExecute
                ? ExecuteProcessor(xmlDoc, recMsgDirs, processor.CreateNewInstance(), processor.Execute)
                : ExecuteProcessor(xmlDoc, recMsgDirs, new WXBaseRecMsg(), null);

            ExecuteEnd(context);

            return(new Resp <WXChatContext>(context));
        }
Example #4
0
        /// <summary>
        /// 核心执行 过程的  验签和解密
        /// </summary>
        /// <returns>验证结果及相应的消息内容体 (如果加密模式,返回的是解密后的明文)</returns>
        private static StrResp Prepare(WXChatConfig appConfig, string recXml, string signature, string msg_signature,
                                       string timestamp, string nonce)
        {
            var isEncryptMsg = appConfig.SecurityType == WXSecurityType.Safe;

            if (!isEncryptMsg)
            {
                var resCheck = WXChatHelper.CheckSignature(appConfig.Token, signature, timestamp, nonce, String.Empty);
                return(!resCheck.IsSuccess() ? new StrResp().WithResp(resCheck) : new StrResp(recXml));
            }

            if (string.IsNullOrEmpty(msg_signature))
            {
                return(new StrResp().WithResp(RespTypes.ParaError, "msg_signature 消息体验证签名参数为空!"));
            }

            var xmlDoc   = WXChatHelper.GetXmlDocment(recXml);
            var encryStr = xmlDoc?.FirstChild["Encrypt"]?.InnerText;

            if (string.IsNullOrEmpty(encryStr))
            {
                return(new StrResp().WithResp(RespTypes.ObjectNull, "安全接口的加密字段为空!"));
            }

            var cryptMsgCheck = WXChatHelper.CheckSignature(appConfig.Token, msg_signature, timestamp, nonce, encryStr);

            if (!cryptMsgCheck.IsSuccess())
            {
                return(new StrResp().WithResp(cryptMsgCheck));
            }

            var recMsgXml = Cryptography.AESDecrypt(encryStr, appConfig.EncodingAesKey);

            return(new StrResp(recMsgXml));
        }
Example #5
0
        /// <summary>
        /// 核心执行方法
        /// </summary>
        /// <param name="recMsgXml">传入消息的xml</param>
        /// <returns></returns>
        protected virtual async Task <Resp <WXChatContext> > Processing(string recMsgXml)
        {
            var recMsgDirs = WXChatHelper.ChangXmlToDir(recMsgXml, out var xmlDoc);

            recMsgDirs.TryGetValue("MsgType", out var msgType);
            string eventName = null;

            if (msgType == "event")
            {
                if (!recMsgDirs.TryGetValue("Event", out eventName))
                {
                    return(new Resp <WXChatContext>().WithResp(RespTypes.ParaError, "事件消息数据中未发现 事件类型(Event)字段!"));
                }
            }

            var processor = GetInternalMsgProcessor(msgType, eventName)
                            ?? GetCustomProcessor(msgType, eventName, recMsgDirs);

            var context = await(processor != null
                ? ExecuteProcessor(xmlDoc, recMsgDirs, processor)
                : ExecuteProcessor(xmlDoc, recMsgDirs, SingleInstance <InternalWXChatProcessor> .Instance));

            await ExecuteEnd(context);

            return(new Resp <WXChatContext>(context));
        }
Example #6
0
        /// <summary>
        ///  服务器验证
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="echostr"></param>
        /// <returns></returns>
        public Resp <string> CheckServerValid(string signature, string timestamp, string nonce, string echostr)
        {
            var checkSignRes = WXChatHelper.CheckSignature(ApiConfig.Token, signature, timestamp, nonce);

            var resultRes = new Resp <string>().WithResp(checkSignRes);// checkSignRes.ConvertToResult<string>();

            resultRes.data = resultRes.IsSuccess() ? echostr : string.Empty;

            return(resultRes);
        }
Example #7
0
        /// <summary>
        /// 消息处理入口
        /// </summary>
        /// <param name="contentXml">内容信息</param>
        /// <param name="signature">签名信息,请注意不是[msg_signature]</param>
        /// <param name="msg_signature">消息体签名</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonce">随机字符创</param>
        /// <param name="echostr">验证服务器参数,如果存在则只进行签名验证,并将在结果data中返回</param>
        /// <returns>消息结果,Data为响应微信数据,如果出错Message为错误信息</returns>
        public async Task <StrResp> Process(string contentXml, string signature, string msg_signature, string timestamp, string nonce,
                                            string echostr)
        {
            if (string.IsNullOrEmpty(contentXml) || string.IsNullOrEmpty(signature) ||
                string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce))
            {
                return(new StrResp().WithResp(RespTypes.ParaError, "消息相关参数错误!"));
            }

            var appConfigRes = await GetMeta();

            if (!appConfigRes.IsSuccess())
            {
                return(new StrResp().WithResp(appConfigRes));
            }

            var appConfig = appConfigRes.data;

            // 一.  检查是否是微信服务端首次地址配置验证
            if (!string.IsNullOrEmpty(echostr))
            {
                return(CheckServerValid(appConfig, signature, timestamp, nonce, echostr));
            }

            var checkRes = Prepare(appConfig, contentXml, signature, msg_signature, timestamp, nonce);

            if (!checkRes.IsSuccess())
            {
                return(new StrResp().WithResp(checkRes));
            }

            var contextRes = await Processing(checkRes.data);

            if (!contextRes.IsSuccess())
            {
                return(new StrResp().WithResp(contextRes));
            }

            var resultString = contextRes.data.ReplyMsg.ToReplyXml();

            if (appConfig.SecurityType != WXSecurityType.None &&
                !string.IsNullOrEmpty(contextRes.data.ReplyMsg.MsgType))
            {
                return(WXChatHelper.EncryptMsg(resultString, appConfig));
            }
            return(new StrResp(resultString));
        }