Esempio n. 1
0
        public XDocument Init(IEncryptPostModel postModel)
        {
            _postModel = postModel as PostModel ?? new PostModel();

            //解密XML信息
            var postDataStr = EcryptRequestDocument.ToString();

            WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId);
            string        msgXml   = null;
            var           result   = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

            //判断result类型
            if (result != 0)
            {
                //验证没有通过,取消执行
                CancelExecute = true;
                return(null);
            }

            RequestDocument = XDocument.Parse(msgXml);//完成解密
            RequestMessage  = RequestMessageFactory.GetRequestEntity(RequestDocument);

            //((RequestMessageBase)RequestMessage).FillEntityWithXml(RequestDocument);

            return(RequestDocument);
        }
Esempio n. 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="inputStream"></param>
        /// <param name="maxRecordCount"></param>
        /// <param name="postModel">需要传入到Init的参数</param>
        public MessageHandler(Stream inputStream, IEncryptPostModel postModel, int maxRecordCount = 0)
        {
            var postDataDocument = XmlUtility.Convert(inputStream);

            //PostModel = postModel;//PostModel 在当前类初始化过程中必须赋值
            CommonInitialize(postDataDocument, maxRecordCount, postModel);
        }
Esempio n. 3
0
 /// <summary>
 /// 构造函数公用的初始化方法
 /// </summary>
 /// <param name="postDataDocument"></param>
 /// <param name="maxRecordCount"></param>
 /// <param name="postModel"></param>
 public void CommonInitialize(XDocument postDataDocument, int maxRecordCount, IEncryptPostModel postModel)
 {
     OmitRepeatedMessage = true;  //默认开启去重
     GlobalMessageContext.MaxRecordCount = maxRecordCount;
     PostModel       = postModel; //PostModel 在当前类初始化过程中必须赋值
     RequestDocument = Init(postDataDocument, postModel);
 }
Esempio n. 4
0
        /// <summary>
        /// <para>使用requestMessageBase的构造函数</para>
        /// <para>此构造函数提供给具体的类库进行测试使用,例如Senparc.NeuChar.Work</para>
        /// </summary>
        /// <param name="requestMessageBase"></param>
        /// <param name="maxRecordCount"></param>
        /// <param name="postModel">需要传入到Init的参数</param>
        public MessageHandler(RequestMessageBase requestMessageBase, IEncryptPostModel postModel, int maxRecordCount = 0)
        {
            ////将requestMessageBase生成XML格式。
            //var xmlStr = XmlUtility.XmlUtility.Serializer(requestMessageBase);
            //var postDataDocument = XDocument.Parse(xmlStr);

            //CommonInitialize(postDataDocument, maxRecordCount, postData);

            //此方法不执行任何方法,提供给具体的类库进行测试使用,例如Senparc.NeuChar.Work
        }
Esempio n. 5
0
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            _postModel = postModel as PostModel ?? new PostModel();

            var postDataStr = postDataDocument.ToString();

            //Work中消息默认都是强制加密的,但通知似乎没有加密
            UsingEncryptMessage = postDataDocument.Root.Element("Encrypt") != null;

            EncryptPostData = RequestMessageFactory.GetEncryptPostData(postDataStr);

            XDocument requestDocument;

            //2、解密:获得明文字符串
            if (UsingEncryptMessage)
            {
                string msgXml = null;

                WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.CorpId);
                var           result   = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

                /* msgXml
                 * <xml><ToUserName><![CDATA[wx7618c0a6d9358622]]></ToUserName>
                 * <FromUserName><![CDATA[001]]></FromUserName>
                 * <CreateTime>1412585107</CreateTime>
                 * <MsgType><![CDATA[text]]></MsgType>
                 * <Content><![CDATA[你好]]></Content>
                 * <MsgId>4299263624800632834</MsgId>
                 * <AgentID>2</AgentID>
                 * </xml>
                 */

                //判断result类型
                if (result != 0)
                {
                    //验证没有通过,取消执行
                    CancelExecute = true;
                    return(null);
                }

                requestDocument = XDocument.Parse(msgXml);
            }
            else
            {
                requestDocument = postDataDocument;//TODO:深拷贝
            }

            RequestMessage = RequestMessageFactory.GetRequestEntity <TMC>(new TMC(), doc: requestDocument);

            return(requestDocument);

            //消息上下文记录将在 base.CommonInitialize() 中根据去重等条件判断后进行添加
        }
Esempio n. 6
0
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            //进行加密判断并处理
            var postDataStr = postDataDocument.ToString();

            XDocument decryptDoc = postDataDocument;

            //if (postModel != null && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value))
            //{
            //    //使用了加密
            //    UsingEncryptMessage = true;
            //    EcryptRequestDocument = postDataDocument;

            //    WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId);
            //    string msgXml = null;
            //    var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

            //    //判断result类型
            //    if (result != 0)
            //    {
            //        //验证没有通过,取消执行
            //        CancelExcute = true;
            //        return null;
            //    }

            //    if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value))
            //    {
            //        //TODO:使用了兼容模式,进行验证即可
            //        UsingCompatibilityModelEncryptMessage = true;
            //    }

            //    decryptDoc = XDocument.Parse(msgXml);//完成解密
            //}

            var msgType = MsgTypeHelper.GetRequestMsgType(decryptDoc);

            if (msgType != RequestMsgType.NeuChar)
            {
                throw new MessageHandlerException("仅支持 NeuChar 类型请求");
            }

            RequestMessage = new RequestMessageNeuChar();
            if (UsingEncryptMessage)
            {
                RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value;
            }

            return(decryptDoc);

            //消息上下文记录将在 base.CommonInitialize() 中根据去重等条件判断后进行添加
        }
Esempio n. 7
0
        /// <summary>
        /// 初始化数据
        /// </summary>
        /// <param name="postDataDocument"></param>
        /// <param name="postModel"></param>
        /// <returns></returns>
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            //进行加密判断并处理
            _postModel = postModel as PostModel ?? new PostModel();
            var postDataStr = postDataDocument.ToString();

            XDocument decryptDoc = postDataDocument;

            if (_postModel != null && !_postModel.Token.IsNullOrWhiteSpace() &&
                postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value))
            {
                //使用了加密
                UsingEcryptMessage    = true;
                EcryptRequestDocument = postDataDocument;

                WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId);
                string        msgXml   = null;
                var           result   = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

                //判断result类型
                if (result != 0)
                {
                    //验证没有通过,取消执行
                    CancelExcute = true;
                    return(null);
                }

                if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value))
                {
                    //TODO:使用了兼容模式,进行验证即可
                    UsingCompatibilityModelEcryptMessage = true;
                }

                decryptDoc = XDocument.Parse(msgXml);//完成解密
            }

            RequestMessage = RequestMessageFactory.GetRequestEntity(decryptDoc);
            if (UsingEcryptMessage)
            {
                RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value;
            }


            //记录上下文
            if (MessageContextGlobalConfig.UseMessageContext)
            {
                GlobalMessageContext.InsertMessage(RequestMessage);
            }

            return(decryptDoc);
        }
Esempio n. 8
0
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            _postModel = postModel as PostModel ?? new PostModel();


            UsingEcryptMessage = true;//Work中消息都是强制加密的
            var postDataStr = postDataDocument.ToString();

            EncryptPostData = RequestMessageFactory.GetEncryptPostData(postDataStr);

            //2、解密:获得明文字符串
            WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.CorpId);
            string        msgXml   = null;
            var           result   = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

            /* msgXml
             * <xml><ToUserName><![CDATA[wx7618c0a6d9358622]]></ToUserName>
             * <FromUserName><![CDATA[001]]></FromUserName>
             * <CreateTime>1412585107</CreateTime>
             * <MsgType><![CDATA[text]]></MsgType>
             * <Content><![CDATA[你好]]></Content>
             * <MsgId>4299263624800632834</MsgId>
             * <AgentID>2</AgentID>
             * </xml>
             */

            //判断result类型
            if (result != 0)
            {
                //验证没有通过,取消执行
                CancelExcute = true;
                return(null);
            }

            var requestDocument = XDocument.Parse(msgXml);

            RequestMessage = RequestMessageFactory.GetRequestEntity(requestDocument);

            //记录上下文
            if (RequestMessage.MsgType != RequestMsgType.Unknown && MessageContextGlobalConfig.UseMessageContext)
            {
                GlobalMessageContext.InsertMessage(RequestMessage);
            }

            return(requestDocument);
        }
Esempio n. 9
0
        public override XDocument Init(XDocument requestDocument, IEncryptPostModel postModel)
        {
            XDocument decryptDoc     = requestDocument;
            var       messageContext = new Weixin.MP.MessageContexts.DefaultMpMessageContext();// new CustomMessageContext(); //base.GetCurrentMessageContext().GetAwaiter().GetResult();

            RequestMessage = RequestMessageFactory.GetRequestEntity(messageContext, decryptDoc) as RequestMessageBase;

            base.SpecialDeduplicationAction = (lastMessage, messageHandler) =>
            {
                //判断特殊事件
                if (!messageHandler.MessageIsRepeated &&
                    lastMessage is RequestMessageEventBase &&
                    messageHandler.RequestMessage is RequestMessageEventBase &&
                    (lastMessage as RequestMessageEventBase).Event == (messageHandler.RequestMessage as RequestMessageEventBase).Event
                    )
                {
                    var lastEventMessage    = lastMessage as RequestMessageEventBase;
                    var currentEventMessage = messageHandler.RequestMessage as RequestMessageEventBase;
                    switch (lastEventMessage.Event)
                    {
                    case Event.user_get_card:     //领取事件推送
                                                  //文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025274
                                                  //问题反馈:https://github.com/JeffreySu/WeiXinMPSDK/issues/1106
                        var lastGetUserCardMessage    = lastMessage as RequestMessageEvent_User_Get_Card;
                        var currentGetUserCardMessage = messageHandler.RequestMessage as RequestMessageEvent_User_Get_Card;
                        if (lastGetUserCardMessage.UserCardCode == currentGetUserCardMessage.UserCardCode &&
                            lastGetUserCardMessage.CardId == currentGetUserCardMessage.CardId)
                        {
                            return(true);
                        }
                        break;

                    default:
                        break;
                    }
                }
                return(false);
            };

            //消息去重的基本方法已经在基类 CommonInitialize() 中实现

            return(decryptDoc);
        }
Esempio n. 10
0
 public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postData = null)
 {
     StartTime = DateTime.Now;
     return(base.Init(postDataDocument, postData));
 }
Esempio n. 11
0
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="postDataDocument"></param>
        /// <param name="postModel"></param>
        /// <returns></returns>
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            //进行加密判断并处理
            _postModel = postModel as PostModel;
            var postDataStr = postDataDocument.ToString();

            XDocument decryptDoc = postDataDocument;

            if (_postModel != null && !_postModel.Token.IsNullOrWhiteSpace() &&
                postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value))
            {
                //使用了加密
                UsingEcryptMessage    = true;
                EcryptRequestDocument = postDataDocument;

                WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId);
                string        msgXml   = null;
                var           result   = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

                //判断result类型
                if (result != 0)
                {
                    //验证没有通过,取消执行
                    CancelExcute = true;
                    return(null);
                }

                if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value))
                {
                    //TODO:使用了兼容模式,进行验证即可
                    UsingCompatibilityModelEcryptMessage = true;
                }

                decryptDoc = XDocument.Parse(msgXml);//完成解密
            }

            RequestMessage = RequestMessageFactory.GetRequestEntity(decryptDoc);
            if (UsingEcryptMessage)
            {
                RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value;
            }


            //TODO:分布式系统中本地的上下文会有同步问题,需要同步使用远程的储存
            if (MessageContextGlobalConfig.UseMessageContext)
            {
                var omit = OmitRepeatedMessageFunc == null || OmitRepeatedMessageFunc(RequestMessage);

                lock (MessageContextGlobalConfig.OmitRepeatLock)//TODO:使用分布式锁
                {
                    #region 消息去重

                    if (omit &&
                        OmitRepeatedMessage &&
                        CurrentMessageContext.RequestMessages.Count > 0
                        //&& !(RequestMessage is RequestMessageEvent_Merchant_Order)批量订单的MsgId可能会相同
                        )
                    {
                        //lastMessage必定有值(除非极端小的过期时间条件下,几乎不可能发生)
                        var lastMessage = CurrentMessageContext.RequestMessages[CurrentMessageContext.RequestMessages.Count - 1];

                        if (
                            //使用MsgId去重
                            (lastMessage.MsgId != 0 && lastMessage.MsgId == RequestMessage.MsgId) ||
                            //使用CreateTime去重(OpenId对象已经是同一个)
                            (lastMessage.MsgId == RequestMessage.MsgId &&
                             lastMessage.CreateTime == RequestMessage.CreateTime &&
                             lastMessage.MsgType == RequestMessage.MsgType)
                            )
                        {
                            MarkRepeatedMessage();//标记为已重复
                        }

                        //判断特殊事件
                        if (!MessageIsRepeated &&
                            lastMessage is RequestMessageEventBase &&
                            RequestMessage is RequestMessageEventBase &&
                            (lastMessage as RequestMessageEventBase).Event == (RequestMessage as RequestMessageEventBase).Event
                            )
                        {
                            var lastEventMessage    = lastMessage as RequestMessageEventBase;
                            var currentEventMessage = RequestMessage as RequestMessageEventBase;
                            switch (lastEventMessage.Event)
                            {
                            case Event.user_get_card:    //领取事件推送
                                //文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025274
                                //问题反馈:https://github.com/JeffreySu/WeiXinMPSDK/issues/1106
                                var lastGetUserCardMessage    = lastMessage as RequestMessageEvent_User_Get_Card;
                                var currentGetUserCardMessage = RequestMessage as RequestMessageEvent_User_Get_Card;
                                if (lastGetUserCardMessage.UserCardCode == currentGetUserCardMessage.UserCardCode &&
                                    lastGetUserCardMessage.CardId == currentGetUserCardMessage.CardId)
                                {
                                    MarkRepeatedMessage();    //标记为已重复
                                }
                                break;

                            default:
                                break;
                            }
                        }
                    }

                    #endregion

                    //在消息没有被去重的情况下记录上下文
                    if (!MessageIsRepeated)
                    {
                        GlobalMessageContext.InsertMessage(RequestMessage);
                    }
                }
            }

            return(decryptDoc);
        }
Esempio n. 12
0
 /// <summary>
 /// 使用postDataDocument的构造函数
 /// </summary>
 /// <param name="postDataDocument"></param>
 /// <param name="maxRecordCount"></param>
 /// <param name="postModel">需要传入到Init的参数</param>
 public MessageHandler(XDocument postDataDocument, IEncryptPostModel postModel, int maxRecordCount = 0)
 {
     //PostModel = postModel;//PostModel 在当前类初始化过程中必须赋值
     CommonInitialize(postDataDocument, maxRecordCount, postModel);
 }
Esempio n. 13
0
 /// <summary>
 /// 初始化,获取RequestDocument。
 /// Init中需要对上下文添加当前消息(如果使用上下文)
 /// </summary>
 /// <param name="requestDocument"></param>
 /// <param name="postModel"></param>
 public abstract XDocument Init(XDocument requestDocument, IEncryptPostModel postModel);
Esempio n. 14
0
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            BeginTime = DateTime.Now;

            return(base.Init(postDataDocument, postModel));
        }
Esempio n. 15
0
 /// <summary>
 /// 使用postDataDocument的构造函数
 /// </summary>
 /// <param name="postDataDocument"></param>
 /// <param name="maxRecordCount"></param>
 /// <param name="postModel">需要传入到Init的参数</param>
 public MessageHandler(XDocument postDataDocument, IEncryptPostModel postModel, int maxRecordCount = 0)
 {
     CommonInitialize(postDataDocument, maxRecordCount, postModel);
 }
Esempio n. 16
0
 /// <summary>
 /// 检查签名是否正确
 /// </summary>
 /// <param name="signature"></param>
 /// <param name="postModel">需要提供:Timestamp、Nonce、Token</param>
 /// <returns></returns>
 public static bool Check(string signature, IEncryptPostModel postModel)
 {
     return(Check(signature, postModel.Timestamp, postModel.Nonce, postModel.Token));
 }
Esempio n. 17
0
        public override XDocument Init(XDocument postDataDocument, IEncryptPostModel postModel)
        {
            //进行加密判断并处理
            var postDataStr = postDataDocument.ToString();

            XDocument decryptDoc = postDataDocument;

            //if (postModel != null && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value))
            //{
            //    //使用了加密
            //    UsingEcryptMessage = true;
            //    EcryptRequestDocument = postDataDocument;

            //    WXBizMsgCrypt msgCrype = new WXBizMsgCrypt(_postModel.Token, _postModel.EncodingAESKey, _postModel.AppId);
            //    string msgXml = null;
            //    var result = msgCrype.DecryptMsg(_postModel.Msg_Signature, _postModel.Timestamp, _postModel.Nonce, postDataStr, ref msgXml);

            //    //判断result类型
            //    if (result != 0)
            //    {
            //        //验证没有通过,取消执行
            //        CancelExcute = true;
            //        return null;
            //    }

            //    if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value))
            //    {
            //        //TODO:使用了兼容模式,进行验证即可
            //        UsingCompatibilityModelEcryptMessage = true;
            //    }

            //    decryptDoc = XDocument.Parse(msgXml);//完成解密
            //}

            var msgType = MsgTypeHelper.GetRequestMsgType(decryptDoc);

            if (msgType != RequestMsgType.NeuChar)
            {
                throw new MessageHandlerException("仅支持 NeuChar 类型请求");
            }

            RequestMessage = new RequestMessageNeuChar();
            if (UsingEcryptMessage)
            {
                RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value;
            }

            //TODO:分布式系统中本地的上下文会有同步问题,需要同步使用远程的储存
            if (MessageContextGlobalConfig.UseMessageContext)
            {
                //var omit = OmitRepeatedMessageFunc == null || OmitRepeatedMessageFunc(RequestMessage);

                var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance();
                using (cache.BeginCacheLock(MessageContextGlobalConfig.MESSAGE_CONTENT_OMIT_REPEAT_LOCK_NAME, "NeuCharAppMessageHandler"))//使用分布式缓存
                {
                    #region 消息去重

                    if (/*omit &&*/
                        OmitRepeatedMessage &&
                        CurrentMessageContext.RequestMessages.Count > 0
                        //&& !(RequestMessage is RequestMessageEvent_Merchant_Order)批量订单的MsgId可能会相同
                        )
                    {
                        //lastMessage必定有值(除非极端小的过期时间条件下,几乎不可能发生)
                        var lastMessage = CurrentMessageContext.RequestMessages[CurrentMessageContext.RequestMessages.Count - 1];

                        if (
                            //使用MsgId去重
                            (lastMessage.MsgId != 0 && lastMessage.MsgId == RequestMessage.MsgId) ||
                            //使用CreateTime去重(OpenId对象已经是同一个)
                            (lastMessage.MsgId == RequestMessage.MsgId &&
                             lastMessage.CreateTime == RequestMessage.CreateTime &&
                             lastMessage.MsgType == RequestMessage.MsgType)
                            )
                        {
                            MarkRepeatedMessage();//标记为已重复
                        }
                    }

                    #endregion

                    //在消息没有被去重的情况下记录上下文
                    if (!MessageIsRepeated)
                    {
                        GlobalMessageContext.InsertMessage(RequestMessage);
                    }
                }
            }

            return(decryptDoc);
        }
Esempio n. 18
0
        ///// <summary>
        ///// 动态去重判断委托,仅当返回值为false时,不使用消息去重功能
        ///// </summary>
        //public Func<IRequestMessageBase, bool> OmitRepeatedMessageFunc { get; set; } = null;


        public CustomMessageHandler(XDocument postDataDocument, IEncryptPostModel postModel, int maxRecordCount = 0)
            : base(postDataDocument, postModel, maxRecordCount)
        {
        }
Esempio n. 19
0
 /// <summary>
 /// 返回正确的签名
 /// </summary>
 /// <param name="postModel">需要提供:Timestamp、Nonce、Token</param>
 /// <returns></returns>
 public static string GetSignature(IEncryptPostModel postModel)
 {
     return(GetSignature(postModel.Timestamp, postModel.Nonce, postModel.Token));
 }