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); }
/// <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 }