Example #1
0
        public void ExecuteTest_EncryptMessageHandle()
        {
            const string xml = @"<xml>
                                     <ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName>
                                     <Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt>
                                 </xml>";

            WeixinMessageContext context = new WeixinMessageContext()
            {
                HttpRequestContent = xml,
                HttpRequestParams  = new HttpRequestParams()
                {
                    Encrypt_Type  = "aes",
                    Signature     = "d2157f2f9079f4d6257b45edf665c43c62e60a0a",
                    Timestamp     = "1409659813",
                    Nonce         = "1372623149",
                    Msg_Signature = "477715d11cdb4164915debcba66cb864d751f3e6"
                }
            };

            WeixinMessageHandler handler = new WeixinMessageHandler(context);

            string content = handler.Execute();

            Assert.NotNull(content);
            Assert.True(content.Length > 0);

            //解密校验结果是否正确,
            dynamic resultXmlObj = new DynamicXml(content);

            Assert.Equal(context.HttpRequestParams.Timestamp, resultXmlObj.TimeStamp.Value);
            Assert.Equal(context.HttpRequestParams.Nonce, resultXmlObj.Nonce.Value);
            Assert.True(resultXmlObj.Encrypt.Value.Length > 0);

            //获取消息签名 后期解密字符串使用。
            string msgSignature = resultXmlObj.MsgSignature.Value;

            Assert.True(msgSignature.Length > 0);

            string          sMsg      = string.Empty;
            WeixinMsgCrypto msgCrypto = new WeixinMsgCrypto();
            int             resultXmlDecryptResult = msgCrypto.DecryptMsg(msgSignature, context.HttpRequestParams.Timestamp, context.HttpRequestParams.Nonce, content, ref sMsg);

            Assert.Equal(Convert.ToInt32(WeixinMsgCryptoErrorCode.OK), resultXmlDecryptResult);
            Assert.True(sMsg.Length > 0);

            //解密后的 xml 结果 测试。
            dynamic contentXmlObj = new DynamicXml(sMsg);

            Assert.Equal("mycreate", contentXmlObj.ToUserName.Value);
            Assert.Equal("wx5823bf96d3bd56c7", contentXmlObj.FromUserName.Value);
            Assert.True(Convert.ToInt64(contentXmlObj.CreateTime.Value) > 0);
            Assert.Equal("text", contentXmlObj.MsgType.Value);
            Assert.Equal("hello", contentXmlObj.Content.Value);
        }
Example #2
0
        /// <summary>
        /// 执行消息处理。
        /// </summary>
        private void ExecMessageHandler()
        {
            #region 参数校验

            if (string.IsNullOrEmpty(this.MessageContext.HttpRequestContent))
            {
                throw new StringNullOrEmptyException("HttpRequestContent");
            }

            if (this.MessageContext.HttpRequestParams == null)
            {
                throw new StringNullOrEmptyException("HttpRequestParams");
            }

            #endregion

            #region 初始化参数

            this._requestParams  = this.MessageContext.HttpRequestParams;
            this._requestContent = this.MessageContext.HttpRequestContent;

            #endregion

            #region 校验签名

            CheckSignature.Execute(this._requestParams.Signature, this._requestParams.Timestamp, this._requestParams.Nonce, string.Empty);

            #endregion

            #region 消息解密

            if (this._requestParams.IsEncrypt)
            {
                this._msgCrypto = new WeixinMsgCrypto();
                int decryptMsgResult = this._msgCrypto.DecryptMsg(this._requestParams.Msg_Signature, this._requestParams.Timestamp, this._requestParams.Nonce, this._requestContent, ref this._requestContent);
                if (decryptMsgResult != Convert.ToInt32(WeixinMsgCryptoErrorCode.OK))
                {
                    throw new Exception("消息解密失败!");
                }
            }

            #endregion

            //消息解析。
            this._requestMessage = RequestMessageProcess.Parse(this._requestContent);

            if (this._requestMessage == null)
            {
                this._responeContent = string.Empty;
                //记录日志。
                WeixinApp.Logger.Info($"消息未处理,requestContent:{this._requestContent}");
                return;
            }

            #region 会话支持

            //todo: 后期实现。

            #endregion

            #region 消息去重

            #region  除无效的消息标识

            for (int i = 0; i < _messageIdentitys.Count; i++)
            {
                KeyValuePair <string, DateTime> item = _messageIdentitys[i];

                //如果消息处理时间大于 30 秒则删除该条标识。
                if (item.Value.AddSeconds(30) < DateTime.Now)
                {
                    _messageIdentitys.Remove(item);
                }
            }

            #endregion

            string msgIdentity = this.GetMessageIdentity(this._requestMessage);

            //如果消息已经被标识为处理则返回空字符串,
            if (_messageIdentitys.Any(i => i.Key == msgIdentity))
            {
                this._responeContent = string.Empty;

                //记录日志。
                WeixinApp.Logger.Info($"消息重复,已经响应空字符串消息,消息标识:[{msgIdentity}]\r\n请求内容:{_requestContent}");
                return;
            }

            //将当前消息标识添加到标识列表中,
            _messageIdentitys.Add(new KeyValuePair <string, DateTime>(msgIdentity, DateTime.Now));

            #endregion

            //消息处理。
            this._responeContent = RequestMessageProcess.ProcessByConfig(this._requestContent);

            #region 消息加密

            if (this._requestParams.IsEncrypt)
            {
                int encryptMsgResult = this._msgCrypto.EncryptMsg(this._responeContent, this._requestParams.Timestamp, this._requestParams.Nonce, ref this._responeContent);
                if (encryptMsgResult != Convert.ToInt32(WeixinMsgCryptoErrorCode.OK))
                {
                    throw new Exception("消息加密失败!");
                }
            }

            #endregion
        }