コード例 #1
0
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            await next();

            try
            {
                var isDebug = _config.IsDebug;
                if (isDebug)
                {
                    string requestBodyText = string.Empty;
                    var    request         = context.HttpContext.Request;
                    var    method          = request.Method.ToUpper();
                    var    url             = HttpUtility.UrlDecode(UriHelper.GetDisplayUrl(request));
                    var    macName         = Environment.MachineName;
                    var    requestIp       = _webHelper.GetCurrentIpAddress();
                    var    bodyText        = ActionFilterHelper.GetRequestBodyText(request);
                    if (Regex.IsMatch(bodyText, "(\\d+?,)+"))
                    {
                        var index = url.IndexOf('?');
                        if (index > -1)
                        {
                            url = url.Substring(0, index);
                        }
                        string filePath = Path.Combine("C:", "BadUrls");
                        await WriteTxt(filePath, $"{request.Host.Port}.txt", url);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "【ReqeustBodyFilter】error:" + ex.Message);
            }
        }
コード例 #2
0
        public async Task <bool> Handle(IDotvvmRequestContext context)
        {
            var requestTracer = context.Services.GetRequiredService <AggregateRequestTracer>();

            await requestTracer.TraceEvent(RequestTracingConstants.BeginRequest, context);

            IDictionary <string, object> parameters;
            var route = FindMatchingRoute(context.Configuration.RouteTable, context, out parameters);

            //check if route exists
            if (route == null)
            {
                return(false);
            }

            context.Route      = route;
            context.Parameters = parameters;

            var presenter = context.Presenter = route.GetPresenter(context.Services);
            var filters   =
                ActionFilterHelper.GetActionFilters <IPageActionFilter>(presenter.GetType().GetTypeInfo())
                .Concat(context.Configuration.Runtime.GlobalFilters.OfType <IPageActionFilter>());

            try
            {
                foreach (var f in filters)
                {
                    await f.OnPageLoadingAsync(context);
                }
                await presenter.ProcessRequest(context);

                foreach (var f in filters)
                {
                    await f.OnPageLoadedAsync(context);
                }
            }
            catch (DotvvmInterruptRequestExecutionException) { } // the response has already been generated, do nothing
            catch (DotvvmHttpException) { throw; }
            catch (Exception exception)
            {
                foreach (var f in filters)
                {
                    await f.OnPageExceptionAsync(context, exception);

                    if (context.IsPageExceptionHandled)
                    {
                        context.InterruptRequest();
                    }
                }
                await requestTracer.EndRequest(context, exception);

                throw;
            }

            await requestTracer.EndRequest(context);

            return(true);
        }
コード例 #3
0
ファイル: DotvvmPresenter.cs プロジェクト: jdiss/dotvvm
        public async Task ProcessStaticCommandRequest(IDotvvmRequestContext context)
        {
            JObject postData;

            using (var jsonReader = new JsonTextReader(new StreamReader(context.HttpContext.Request.Body)))
            {
                postData = JObject.Load(jsonReader);
            }
            // validate csrf token
            context.CsrfToken = postData["$csrfToken"].Value <string>();
            CsrfProtector.VerifyToken(context, context.CsrfToken);

            var command    = postData["command"].Value <string>();
            var arguments  = postData["args"] as JArray;
            var lastDot    = command.LastIndexOf('.');
            var typeName   = command.Remove(lastDot);
            var methodName = command.Substring(lastDot + 1);
            var methodInfo = Type.GetType(typeName).GetMethod(methodName);

            if (!methodInfo.IsDefined(typeof(AllowStaticCommandAttribute)))
            {
                throw new DotvvmHttpException($"This method cannot be called from the static command. If you need to call this method, add the '{nameof(AllowStaticCommandAttribute)}' to the method.");
            }
            var target          = methodInfo.IsStatic ? null : arguments[0].ToObject(methodInfo.DeclaringType);
            var methodArguments =
                arguments.Skip(methodInfo.IsStatic ? 0 : 1)
                .Zip(methodInfo.GetParameters(), (arg, parameter) => arg.ToObject(parameter.ParameterType))
                .ToArray();
            var actionInfo = new ActionInfo
            {
                IsControlCommand = false,
                Action           = () => methodInfo.Invoke(target, methodArguments)
            };
            var filters = context.Configuration.Runtime.GlobalFilters.OfType <ICommandActionFilter>()
                          .Concat(ActionFilterHelper.GetActionFilters <ICommandActionFilter>(methodInfo))
                          .ToArray();

            var result = await ExecuteCommand(actionInfo, context, filters);

            using (var writer = new StreamWriter(context.HttpContext.Response.Body))
            {
                var json = ViewModelSerializer.BuildStaticCommandResponse(context, result);
                writer.WriteLine(json);
            }
        }
コード例 #4
0
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            int requestWarning = _config.RequestWarningThreshold < 3 ? 3 : _config.RequestWarningThreshold;

            var stopWatch = new Stopwatch();

            stopWatch.Start();

            var executedContext = await next();

            stopWatch.Stop();
            try
            {
                //如果执行超过设定的阈值则记录日志
                long   executeTime     = stopWatch.ElapsedMilliseconds / 1000;
                string requestBodyText = string.Empty;
                var    request         = context.HttpContext.Request;
                var    method          = request.Method.ToUpper();
                var    url             = UriHelper.GetDisplayUrl(request);
                var    macName         = Environment.MachineName;
                var    requestIp       = _webHelper.GetCurrentIpAddress();
                var    bodyText        = ActionFilterHelper.GetRequestBodyText(request, _configuration.GetValue <string>("AliyunLogRule:Regex"));
                if (executeTime >= requestWarning)
                {
                    _logger.Warning("请求时间超过阈值.执行时间:{0}秒.请求url:{1},请求Body:{2},请求IP:{3},服务器名称:{4}",
                                    stopWatch.ElapsedMilliseconds / 1000, url, bodyText, requestIp, macName);
                }
                if (!context.HttpContext.Response.Headers.ContainsKey("x-time-elapsed"))
                {
                    context.HttpContext.Response.Headers.Add(
                        "x-time-elapsed",
                        stopWatch.Elapsed.ToString());
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获得基础信息写入阿里云日志时异常!");
            }
        }
コード例 #5
0
ファイル: DotvvmPresenter.cs プロジェクト: vstribrny/dotvvm
        public async Task ProcessStaticCommandRequest(IDotvvmRequestContext context)
        {
            try
            {
                JObject postData;
                using (var jsonReader = new JsonTextReader(new StreamReader(context.HttpContext.Request.Body)))
                {
                    postData = JObject.Load(jsonReader);
                }

                // validate csrf token
                context.CsrfToken = postData["$csrfToken"].Value <string>();
                CsrfProtector.VerifyToken(context, context.CsrfToken);

                var command       = postData["command"].Value <string>();
                var arguments     = postData["args"] as JArray;
                var executionPlan =
                    StaticCommandBindingCompiler.DecryptJson(Convert.FromBase64String(command), context.Services.GetService <IViewModelProtector>())
                    .Apply(StaticCommandBindingCompiler.DeserializePlan);

                var actionInfo = new ActionInfo {
                    IsControlCommand = false,
                    Action           = () => { return(ExecuteStaticCommandPlan(executionPlan, new Queue <JToken>(arguments), context)); }
                };
                var filters = context.Configuration.Runtime.GlobalFilters.OfType <ICommandActionFilter>()
                              .Concat(executionPlan.GetAllMethods().SelectMany(m => ActionFilterHelper.GetActionFilters <ICommandActionFilter>(m)))
                              .ToArray();

                var result = await ExecuteCommand(actionInfo, context, filters);

                await OutputRenderer.WriteStaticCommandResponse(context,
                                                                ViewModelSerializer.BuildStaticCommandResponse(context, result));
            }
            finally
            {
                StaticCommandServiceLoader.DisposeStaticCommandServices(context);
            }
        }
コード例 #6
0
ファイル: DotvvmPresenter.cs プロジェクト: vstribrny/dotvvm
        /// <summary>
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task ProcessRequestCore(IDotvvmRequestContext context)
        {
            var requestTracer = context.Services.GetRequiredService <AggregateRequestTracer>();

            if (context.HttpContext.Request.Method != "GET" && context.HttpContext.Request.Method != "POST")
            {
                // unknown HTTP method
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
                throw new DotvvmHttpException("Only GET and POST methods are supported!");
            }
            if (context.HttpContext.Request.Headers["X-PostbackType"] == "StaticCommand")
            {
                await ProcessStaticCommandRequest(context);

                await requestTracer.TraceEvent(RequestTracingConstants.StaticCommandExecuted, context);

                return;
            }
            var isPostBack = context.IsPostBack = DetermineIsPostBack(context.HttpContext);

            // build the page view
            var page = DotvvmViewBuilder.BuildView(context);

            page.SetValue(Internal.RequestContextProperty, context);
            context.View = page;
            await requestTracer.TraceEvent(RequestTracingConstants.ViewInitialized, context);

            // locate and create the view model
            context.ViewModel = ViewModelLoader.InitializeViewModel(context, page);

            // get action filters
            var viewModelFilters = ActionFilterHelper.GetActionFilters <IViewModelActionFilter>(context.ViewModel.GetType().GetTypeInfo())
                                   .Concat(context.Configuration.Runtime.GlobalFilters.OfType <IViewModelActionFilter>());

            var requestFilters = ActionFilterHelper.GetActionFilters <IPageActionFilter>(context.ViewModel.GetType().GetTypeInfo())
                                 .Concat(context.Configuration.Runtime.GlobalFilters.OfType <IPageActionFilter>());

            foreach (var f in requestFilters)
            {
                await f.OnPageInitializedAsync(context);
            }
            try
            {
                // run the preinit phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.PreInit);
                page.DataContext = context.ViewModel;

                // run OnViewModelCreated on action filters
                foreach (var filter in viewModelFilters)
                {
                    await filter.OnViewModelCreatedAsync(context);
                }
                await requestTracer.TraceEvent(RequestTracingConstants.ViewModelCreated, context);

                // perform parameter binding
                if (context.ViewModel is DotvvmViewModelBase dotvvmViewModelBase)
                {
                    dotvvmViewModelBase.ExecuteOnViewModelRecursive(v => ViewModelParameterBinder.BindParameters(context, v));
                }
                else
                {
                    ViewModelParameterBinder.BindParameters(context, context.ViewModel);
                }

                // init the view model lifecycle
                if (context.ViewModel is IDotvvmViewModel viewModel)
                {
                    viewModel.Context = context;
                    ChildViewModelsCache.SetViewModelClientPath(viewModel, ChildViewModelsCache.RootViewModelPath);
                    await viewModel.Init();
                }

                // run the init phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.Init);
                await requestTracer.TraceEvent(RequestTracingConstants.InitCompleted, context);

                object commandResult = null;

                if (!isPostBack)
                {
                    // perform standard get
                    if (context.ViewModel is IDotvvmViewModel)
                    {
                        await((IDotvvmViewModel)context.ViewModel).Load();
                    }

                    // run the load phase in the page
                    DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.Load);
                    await requestTracer.TraceEvent(RequestTracingConstants.LoadCompleted, context);
                }
                else
                {
                    // perform the postback
                    string postData;
                    using (var sr = new StreamReader(context.HttpContext.Request.Body))
                    {
                        postData = await sr.ReadToEndAsync();
                    }
                    ViewModelSerializer.PopulateViewModel(context, postData);

                    // run OnViewModelDeserialized on action filters
                    foreach (var filter in viewModelFilters)
                    {
                        await filter.OnViewModelDeserializedAsync(context);
                    }
                    await requestTracer.TraceEvent(RequestTracingConstants.ViewModelDeserialized, context);

                    // validate CSRF token
                    try
                    {
                        CsrfProtector.VerifyToken(context, context.CsrfToken);
                    }
                    catch (SecurityException exc)
                    {
                        await context.InterruptRequestAsync(HttpStatusCode.BadRequest, exc.Message);
                    }

                    if (context.ViewModel is IDotvvmViewModel)
                    {
                        await((IDotvvmViewModel)context.ViewModel).Load();
                    }

                    // run the load phase in the page
                    DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.Load);
                    await requestTracer.TraceEvent(RequestTracingConstants.LoadCompleted, context);

                    // invoke the postback command
                    var actionInfo = ViewModelSerializer.ResolveCommand(context, page);

                    // get filters
                    var methodFilters = context.Configuration.Runtime.GlobalFilters.OfType <ICommandActionFilter>()
                                        .Concat(ActionFilterHelper.GetActionFilters <ICommandActionFilter>(context.ViewModel.GetType().GetTypeInfo()));
                    if (actionInfo.Binding.GetProperty <ActionFiltersBindingProperty>(ErrorHandlingMode.ReturnNull) is ActionFiltersBindingProperty filters)
                    {
                        methodFilters = methodFilters.Concat(filters.Filters.OfType <ICommandActionFilter>());
                    }

                    commandResult = await ExecuteCommand(actionInfo, context, methodFilters);

                    await requestTracer.TraceEvent(RequestTracingConstants.CommandExecuted, context);
                }

                if (context.ViewModel is IDotvvmViewModel)
                {
                    await((IDotvvmViewModel)context.ViewModel).PreRender();
                }

                // run the prerender phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.PreRender);

                // run the prerender complete phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.PreRenderComplete);
                await requestTracer.TraceEvent(RequestTracingConstants.PreRenderCompleted, context);

                // generate CSRF token if required
                if (string.IsNullOrEmpty(context.CsrfToken))
                {
                    context.CsrfToken = CsrfProtector.GenerateToken(context);
                }

                // run OnViewModelSerializing on action filters
                foreach (var filter in viewModelFilters)
                {
                    await filter.OnViewModelSerializingAsync(context);
                }
                await requestTracer.TraceEvent(RequestTracingConstants.ViewModelSerialized, context);

                // render the output
                ViewModelSerializer.BuildViewModel(context);
                if (commandResult != null)
                {
                    context.ViewModelJson["commandResult"] = JToken.FromObject(commandResult);
                }
                if (!context.IsInPartialRenderingMode)
                {
                    // standard get
                    await OutputRenderer.WriteHtmlResponse(context, page);
                }
                else
                {
                    // postback or SPA content
                    var postBackUpdates = OutputRenderer.RenderPostbackUpdatedControls(context, page);
                    ViewModelSerializer.AddPostBackUpdatedControls(context, postBackUpdates);
                    await OutputRenderer.WriteViewModelResponse(context, page);
                }
                await requestTracer.TraceEvent(RequestTracingConstants.OutputRendered, context);

                foreach (var f in requestFilters)
                {
                    await f.OnPageRenderedAsync(context);
                }
            }
            catch (DotvvmInterruptRequestExecutionException) { throw; }
            catch (DotvvmHttpException) { throw; }
            catch (Exception ex)
            {
                // run OnPageException on action filters
                foreach (var filter in requestFilters)
                {
                    await filter.OnPageExceptionAsync(context, ex);

                    if (context.IsPageExceptionHandled)
                    {
                        context.InterruptRequest();
                    }
                }

                throw;
            }
            finally
            {
                if (context.ViewModel != null)
                {
                    ViewModelLoader.DisposeViewModel(context.ViewModel);
                }
                StaticCommandServiceLoader.DisposeStaticCommandServices(context);
            }
        }
コード例 #7
0
        /// <summary>
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task ProcessRequestCore(IDotvvmRequestContext context)
        {
            if (context.HttpContext.Request.Method != "GET" && context.HttpContext.Request.Method != "POST")
            {
                // unknown HTTP method
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
                throw new DotvvmHttpException("Only GET and POST methods are supported!");
            }
            if (context.HttpContext.Request.Headers["X-PostbackType"] == "StaticCommand")
            {
                await ProcessStaticCommandRequest(context);

                return;
            }
            var isPostBack = context.IsPostBack = DetermineIsPostBack(context.HttpContext);

            // build the page view
            var page = DotvvmViewBuilder.BuildView(context);

            page.SetValue(Internal.RequestContextProperty, context);
            context.View = page;

            // locate and create the view model
            context.ViewModel = ViewModelLoader.InitializeViewModel(context, page);

            // get action filters
            var viewModelFilters = ActionFilterHelper.GetActionFilters <IViewModelActionFilter>(context.ViewModel.GetType().GetTypeInfo());

            viewModelFilters.AddRange(context.Configuration.Runtime.GlobalFilters.OfType <IViewModelActionFilter>());
            var requestFilters = ActionFilterHelper.GetActionFilters <IRequestActionFilter>(context.ViewModel.GetType().GetTypeInfo());

            foreach (var f in requestFilters)
            {
                await f.OnPageLoadingAsync(context);
            }

            try
            {
                // run the preinit phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.PreInit);
                page.DataContext = context.ViewModel;

                // run OnViewModelCreated on action filters
                foreach (var filter in viewModelFilters)
                {
                    await filter.OnViewModelCreatedAsync(context);
                }

                // init the view model lifecycle
                if (context.ViewModel is IDotvvmViewModel)
                {
                    ((IDotvvmViewModel)context.ViewModel).Context = context;
                    await((IDotvvmViewModel)context.ViewModel).Init();
                }

                // run the init phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.Init);

                if (!isPostBack)
                {
                    // perform standard get
                    if (context.ViewModel is IDotvvmViewModel)
                    {
                        await((IDotvvmViewModel)context.ViewModel).Load();
                    }

                    // run the load phase in the page
                    DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.Load);
                }
                else
                {
                    // perform the postback
                    string postData;
                    using (var sr = new StreamReader(context.HttpContext.Request.Body))
                    {
                        postData = await sr.ReadToEndAsync();
                    }
                    ViewModelSerializer.PopulateViewModel(context, postData);

                    // validate CSRF token
                    CsrfProtector.VerifyToken(context, context.CsrfToken);

                    if (context.ViewModel is IDotvvmViewModel)
                    {
                        await((IDotvvmViewModel)context.ViewModel).Load();
                    }

                    // validate CSRF token
                    CsrfProtector.VerifyToken(context, context.CsrfToken);

                    // run the load phase in the page
                    DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.Load);

                    // invoke the postback command
                    ActionInfo actionInfo;
                    ViewModelSerializer.ResolveCommand(context, page, postData, out actionInfo);

                    if (actionInfo != null)
                    {
                        // get filters
                        var methodFilters = context.Configuration.Runtime.GlobalFilters.OfType <ICommandActionFilter>()
                                            .Concat(ActionFilterHelper.GetActionFilters <ICommandActionFilter>(context.ViewModel.GetType().GetTypeInfo()));
                        if (actionInfo.Binding.ActionFilters != null)
                        {
                            methodFilters = methodFilters.Concat(actionInfo.Binding.ActionFilters.OfType <ICommandActionFilter>());
                        }

                        await ExecuteCommand(actionInfo, context, methodFilters);
                    }
                }

                if (context.ViewModel is IDotvvmViewModel)
                {
                    await((IDotvvmViewModel)context.ViewModel).PreRender();
                }

                // run the prerender phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.PreRender);

                // run the prerender complete phase in the page
                DotvvmControlCollection.InvokePageLifeCycleEventRecursive(page, LifeCycleEventType.PreRenderComplete);

                // generate CSRF token if required
                if (string.IsNullOrEmpty(context.CsrfToken))
                {
                    context.CsrfToken = CsrfProtector.GenerateToken(context);
                }

                // run OnResponseRendering on action filters
                foreach (var filter in viewModelFilters)
                {
                    await filter.OnResponseRenderingAsync(context);
                }

                // render the output
                ViewModelSerializer.BuildViewModel(context);
                if (!context.IsInPartialRenderingMode)
                {
                    // standard get
                    await OutputRenderer.WriteHtmlResponse(context, page);
                }
                else
                {
                    // postback or SPA content
                    OutputRenderer.RenderPostbackUpdatedControls(context, page);
                    ViewModelSerializer.AddPostBackUpdatedControls(context);
                    await OutputRenderer.WriteViewModelResponse(context, page);
                }

                if (context.ViewModel != null)
                {
                    ViewModelLoader.DisposeViewModel(context.ViewModel);
                }

                foreach (var f in requestFilters)
                {
                    await f.OnPageLoadedAsync(context);
                }
            }
            catch (DotvvmInterruptRequestExecutionException) { throw; }
            catch (DotvvmHttpException) { throw; }
            catch (Exception ex)
            {
                // run OnPageException on action filters
                foreach (var filter in requestFilters)
                {
                    await filter.OnPageExceptionAsync(context, ex);

                    if (context.IsPageExceptionHandled)
                    {
                        context.InterruptRequest();
                    }
                }
                throw;
            }
        }
コード例 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public void OnException(ExceptionContext context)
        {
            string requestBodyText = string.Empty;
            var    request         = context.HttpContext.Request;
            var    method          = request.Method.ToUpper();
            var    url             = UriHelper.GetDisplayUrl(request);
            var    macName         = Environment.MachineName;
            var    requestIp       = _webHelper.GetCurrentIpAddress();
            var    exception       = context.Exception;

            #region 获取body参数
            if (!(exception is ViewModelStateValidException))
            {
                requestBodyText = ActionFilterHelper.GetRequestBodyText(request);
            }
            #endregion

            AppErrorCode errorCode = AppErrorCode.None;
            string       requestId = string.Empty;
            var          errorMsg  = "程序访问异常,请稍后重试!";
            //请求bindModel验证失败时 请求body参数
            if (exception is ViewModelStateValidException)
            {
                requestBodyText = ((ViewModelStateValidException)exception).BindModelText;
            }

            HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            //自定义异常,可预见性异常400,不可预见性异常500
            if (exception is NetProException)
            {
                var NetProEx    = (NetProException)context.Exception;
                var exErrorCode = NetProEx.ErrorCode;
                errorMsg = NetProEx.Message;
                //判断errorCode是否为系统定义的错误代码
                if (((AppErrorCode)exErrorCode).IsValid())
                {
                    errorCode = (AppErrorCode)NetProEx.ErrorCode;
                }
                else
                {
                    errorCode = AppErrorCode.None;
                }
                requestId  = NetProEx.RequestId;
                statusCode = HttpStatusCode.BadRequest;
            }
            var appName = "WebApi";
            if (_config != null)
            {
                appName = _config.ApplicationName;
            }
            //错误代码对应的日志级别
            NetProErrorLevel errorLevel = NetProErrorLevel.Error;
            var currentLevel            = errorCode.GetAttributes()?.Get <ErrorCodeLevelAttribute>()?.Level;
            if (currentLevel.HasValue)
            {
                errorLevel = currentLevel.Value;
            }
            LogEventLevel eventLevel = LogEventLevel.Error;
            switch (errorLevel)
            {
            case NetProErrorLevel.Error:
                eventLevel = LogEventLevel.Error;
                break;

            case NetProErrorLevel.Fatal:
                eventLevel = LogEventLevel.Fatal;
                break;

            case NetProErrorLevel.Warning:
                eventLevel = LogEventLevel.Warning;
                exception  = null;
                break;
            }
            //写入日志系统
            _logger.Write(eventLevel, exception, "{0}异常.errorCode:{1},errorMsg:{2},请求url:{3},请求Body:{4},请求IP:{5},服务器名称:{6}", appName, errorCode.Value(), errorMsg, url, requestBodyText, requestIp, macName);
            //自定义异常返回
            if (_config.AppType == AppType.Api)
            {
                context.Result = errorMsg.ToErrorActionResult(errorCode.Value());
                context.HttpContext.Response.StatusCode = (int)statusCode;
            }
            else
            {
                string errorUrl = _config.ErrorUrl;
                if (string.IsNullOrWhiteSpace(errorUrl) || (!string.IsNullOrWhiteSpace(errorUrl) && errorUrl.Split('/').Length != 2))
                {
                    context.Result = new ContentResult()
                    {
                        Content = "您访问的页面出错!"
                    };
                }
                else
                {
                    var array = errorUrl.Split('/');
                    context.Result = new RedirectToActionResult(array[1], array[0], new { error = exception.Message });
                }
                context.HttpContext.Response.StatusCode = (int)statusCode;
            }
            context.ExceptionHandled = true;
            return;
        }
コード例 #9
0
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var isOpenVerifySign       = _configuration.GetValue("IsOpenVerifySign", false);
            var descriptor             = (Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor;
            var hasIgnoreattribute     = descriptor.MethodInfo.GetCustomAttributes(typeof(IgnoreSignAttribute), true).Any();
            var hasVerifySignAttribute = descriptor.MethodInfo.GetCustomAttributes(typeof(VerifySignAttribute), true).Any();

            //方法不加鉴权特性并且鉴权打开并且有忽略或者方法不加鉴权并且鉴权关闭统一都忽略鉴权否则打开鉴权---方法加鉴权>鉴权开关
            if (!hasVerifySignAttribute && ((isOpenVerifySign && hasIgnoreattribute) || !isOpenVerifySign))
            {
                goto gotoNext;
            }

            string appId    = null;
            string bodyText = null;

            try
            {
                var request = context.HttpContext.Request;
                bodyText = TryPassJsonToQueryString(ActionFilterHelper.GetRequestBodyText(request)?.Trim());
                var allKeys = new Dictionary <string, object>();
                if (!string.IsNullOrWhiteSpace(bodyText))
                {
                    allKeys = bodyText.TrimStart('?').Split('&').Select(a => new
                    {
                        Key   = a.Substring(0, a.IndexOf('=')).ToLower(),
                        Value = (object)a.Substring(a.IndexOf('=') + 1)
                    }).ToDictionary(a => a.Key, a => (object)HttpUtility.UrlDecode(a.Value.ToString()));
                }

                if (request.Headers != null && request.Headers.Keys.Any())
                {
                    var headers = request.Headers.ToDictionary(a => a.Key.ToLower(), a => a.Value).Where(a => new[] { "appid", "sign" }.Contains(a.Key)).ToDictionary(a => a.Key, a => a.Value.ToString());
                    if (headers.Any())
                    {
                        foreach (var header in headers)
                        {
                            if (allKeys.ContainsKey(header.Key))
                            {
                                allKeys[header.Key] = header.Value;
                            }
                            else
                            {
                                allKeys.Add(header.Key, header.Value);
                            }
                        }
                    }
                }

                if (request.Query != null && request.Query.Keys.Any())
                {
                    foreach (var key in request.Query.Keys)
                    {
                        var value    = HttpUtility.UrlDecode(request.Query[key]);
                        var lowerKey = key.ToLower();
                        if (allKeys.ContainsKey(lowerKey))
                        {
                            allKeys[lowerKey] = value;
                        }
                        else
                        {
                            allKeys.Add(lowerKey, value);
                        }
                    }
                }

                if (!allKeys.ContainsKey("appid") || !allKeys.ContainsKey("sign"))
                {
                    BuildErrorJson(context, "不存在AppId/Sign", bodyText);
                    return;
                }

                var secrets = new List <AppSecret>();
                _configuration.GetSection("Secrets").Bind(secrets);
                appId = (string)allKeys["appid"];
                var secret = secrets.FirstOrDefault(a => a.AppId == appId)?.Secret;
                //获取两份签名,一份原始数据,一份忽略大小写的签名。然后用两份签名比较
                var upperSign = SignHelper.GetSign(allKeys, secret);
                var lowerSign = SignHelper.GetSign(allKeys, secret, true);
                var sign      = (string)allKeys["sign"];
                if (upperSign != sign && lowerSign != sign)
                {
                    BuildErrorJson(context, $"签名不正确:sign:{sign},upperSign:{upperSign},lowerSign:{lowerSign}", bodyText);
                    return;
                }
            }
            catch (Exception ex)
            {
                BuildErrorJson(context, "签名验证失败!" + ex.Message, bodyText);
                return;
            }

gotoNext:
            await next();
        }
コード例 #10
0
        public async Task <bool> Handle(IDotvvmRequestContext context)
        {
            // attempt to translate Googlebot hashbang espaced fragment URL to a plain URL string.
            string url;

            if (!TryParseGooglebotHashbangEscapedFragment(context.HttpContext.Request.QueryString, out url))
            {
                url = context.HttpContext.Request.Path.Value;
            }
            url = url.Trim('/');

            // remove SPA identifier from the URL
            if (url.StartsWith(HostingConstants.SpaUrlIdentifier, StringComparison.Ordinal))
            {
                url = url.Substring(HostingConstants.SpaUrlIdentifier.Length).Trim('/');
            }


            // find the route
            IDictionary <string, object> parameters = null;
            var route = context.Configuration.RouteTable.FirstOrDefault(r => r.IsMatch(url, out parameters));

            //check if route exists
            if (route == null)
            {
                return(false);
            }

            context.Route      = route;
            context.Parameters = parameters;

            var presenter = context.Presenter = route.GetPresenter();
            var filters   = ActionFilterHelper.GetActionFilters <IRequestActionFilter>(presenter.GetType().GetTypeInfo());

            filters.AddRange(context.Configuration.Runtime.GlobalFilters.OfType <IRequestActionFilter>());
            try
            {
                foreach (var f in filters)
                {
                    await f.OnPageLoadingAsync(context);
                }
                await presenter.ProcessRequest(context);

                foreach (var f in filters)
                {
                    await f.OnPageLoadedAsync(context);
                }
            }
            catch (DotvvmInterruptRequestExecutionException) { } // the response has already been generated, do nothing
            catch (DotvvmHttpException) { throw; }
            catch (Exception exception)
            {
                foreach (var f in filters)
                {
                    await f.OnPageExceptionAsync(context, exception);

                    if (context.IsPageExceptionHandled)
                    {
                        context.InterruptRequest();
                    }
                }
                throw;
            }
            return(true);
        }
コード例 #11
0
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var descriptor = (Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor;
            var attribute  = (IgnoreSignAttribute)descriptor.MethodInfo.GetCustomAttributes(typeof(IgnoreSignAttribute), true).FirstOrDefault();

            if (attribute != null)
            {
                goto gotoNext;
            }

            string appId = null;

            try
            {
                var request  = context.HttpContext.Request;
                var bodyText = TryPassJsonToQueryString(ActionFilterHelper.GetRequestBodyText(request).Trim());
                if (string.IsNullOrWhiteSpace(bodyText))
                {
                    BuildErrorJson(context);
                    return;
                }
                var allKeys = bodyText.TrimStart('?').Split('&').Select(a => new
                {
                    Key   = a.Substring(0, a.IndexOf('=')).ToLower(),
                    Value = (object)a.Substring(a.IndexOf('=') + 1)
                }).ToDictionary(a => a.Key, a => a.Value);
                if (request.Headers != null)
                {
                    var headers = request.Headers.ToDictionary(a => a.Key.ToLower(), a => a.Value).Where(a => new[] { "appid", "sign" }.Contains(a.Key)).ToDictionary(a => a.Key, a => a.Value.ToString());
                    foreach (var header in headers)
                    {
                        if (allKeys.ContainsKey(header.Key))
                        {
                            allKeys[header.Key] = header.Value;
                        }
                        else
                        {
                            allKeys.Add(header.Key, header.Value);
                        }
                    }
                }
                if (!allKeys.ContainsKey("appid") || !allKeys.ContainsKey("sign"))
                {
                    BuildErrorJson(context);
                    return;
                }

                ////判断请求是否在有效期内
                ////获取过期时间(秒)
                //var expireSeconds = _configuration.GetValue<double>("ExpireSeconds", 0);
                ////请求过期时间
                //var requestExpireTime = new DateTime(ticks + TimeSpan.FromSeconds(expireSeconds).Ticks);
                ////如果请求过期时间小于当前时间则判定为过期
                //if (DateTime.Compare(requestExpireTime, DateTime.Now) == -1)
                //{
                //    BuildErrorJson(context);
                //    return;
                //}

                var secrets = new List <AppSecret>();
                _configuration.GetSection("Secrets").Bind(secrets);
                appId = (string)allKeys["appid"];
                var secret = secrets.FirstOrDefault(a => a.AppId == appId)?.Secret;
                var sign   = SignHelper.GetSign(allKeys, secret);
                if (sign != (string)allKeys["sign"])
                {
                    BuildErrorJson(context);
                    return;
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "【VerifySignFilter】error:" + ex.Message);
                BuildErrorJson(context, "签名验证失败!" + ex.Message);
                return;
            }

gotoNext:
            await next();
        }