using System; using System.Net; using System.Net.Http; using System.Web.Mvc; using Umbraco.Core; namespace Umbraco.Web.Mvc { /// /// Attribute used to check that the request contains a valid Umbraco form request string. /// /// /// /// /// Applying this attribute/filter to a or SurfaceController Action will ensure that the Action can only be executed /// when it is routed to from within Umbraco, typically when rendering a form with BegingUmbracoForm. It will mean that the natural MVC route for this Action /// will fail with a . /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public sealed class ValidateUmbracoFormRouteStringAttribute : FilterAttribute, IAuthorizationFilter { /// /// Called when authorization is required. /// /// The filter context. /// filterContext /// The required request field \"ufprt\" is not present. /// or /// The Umbraco form request route string could not be decrypted. /// or /// The provided Umbraco form request route string was meant for a different controller and action. public void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) throw new ArgumentNullException(nameof(filterContext)); var ufprt = filterContext.HttpContext.Request["ufprt"]; ValidateRouteString(ufprt, filterContext.ActionDescriptor?.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor?.ActionName, filterContext.RouteData?.DataTokens["area"]?.ToString()); } public void ValidateRouteString(string ufprt, string currentController, string currentAction, string currentArea) { if (ufprt.IsNullOrWhiteSpace()) { throw new HttpUmbracoFormRouteStringException("The required request field \"ufprt\" is not present."); } if (!UmbracoHelper.DecryptAndValidateEncryptedRouteString(ufprt, out var additionalDataParts)) { throw new HttpUmbracoFormRouteStringException("The Umbraco form request route string could not be decrypted."); } if (!additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Controller].InvariantEquals(currentController) || !additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Action].InvariantEquals(currentAction) || (!additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Area].IsNullOrWhiteSpace() && !additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Area].InvariantEquals(currentArea))) { throw new HttpUmbracoFormRouteStringException("The provided Umbraco form request route string was meant for a different controller and action."); } } } }