63 lines
3.3 KiB
C#
63 lines
3.3 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Web.Mvc;
|
|
using Umbraco.Core;
|
|
|
|
namespace Umbraco.Web.Mvc
|
|
{
|
|
/// <summary>
|
|
/// Attribute used to check that the request contains a valid Umbraco form request string.
|
|
/// </summary>
|
|
/// <seealso cref="System.Web.Mvc.FilterAttribute" />
|
|
/// <seealso cref="System.Web.Mvc.IAuthorizationFilter" />
|
|
/// <remarks>
|
|
/// Applying this attribute/filter to a <see cref="SurfaceController"/> 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 <see cref="HttpUmbracoFormRouteStringException"/>.
|
|
/// </remarks>
|
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
|
public sealed class ValidateUmbracoFormRouteStringAttribute : FilterAttribute, IAuthorizationFilter
|
|
{
|
|
/// <summary>
|
|
/// Called when authorization is required.
|
|
/// </summary>
|
|
/// <param name="filterContext">The filter context.</param>
|
|
/// <exception cref="ArgumentNullException">filterContext</exception>
|
|
/// <exception cref="Umbraco.Web.Mvc.HttpUmbracoFormRouteStringException">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.</exception>
|
|
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.");
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|