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); } }
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); }
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); } }
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, "获得基础信息写入阿里云日志时异常!"); } }
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); } }
/// <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); } }
/// <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; } }
/// <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; }
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(); }
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); }
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(); }