From 314f9a4e18b490a9f30c0e8347e643541374e932 Mon Sep 17 00:00:00 2001 From: Bertrand Le Roy Date: Tue, 14 Oct 2014 17:19:38 -0700 Subject: [PATCH] Actions can opt out of anti-forgery by adding [AntiForgeryTokenOrchard(false)] --- .../AntiForgeryAuthorizationFilter.cs | 34 +++++++++---------- ...alidateAntiForgeryTokenOrchardAttribute.cs | 9 +++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Orchard/Mvc/AntiForgery/AntiForgeryAuthorizationFilter.cs b/src/Orchard/Mvc/AntiForgery/AntiForgeryAuthorizationFilter.cs index 436d33ef0..e649a3ce7 100644 --- a/src/Orchard/Mvc/AntiForgery/AntiForgeryAuthorizationFilter.cs +++ b/src/Orchard/Mvc/AntiForgery/AntiForgeryAuthorizationFilter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Specialized; +using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; @@ -7,22 +8,20 @@ using JetBrains.Annotations; using Orchard.Environment.Extensions; using Orchard.Mvc.Filters; using Orchard.Security; -using Orchard.Settings; namespace Orchard.Mvc.AntiForgery { [UsedImplicitly] public class AntiForgeryAuthorizationFilter : FilterProvider, IAuthorizationFilter { - private readonly ISiteService _siteService; private readonly IAuthenticationService _authenticationService; private readonly IExtensionManager _extensionManager; - public AntiForgeryAuthorizationFilter(ISiteService siteService, IAuthenticationService authenticationService, IExtensionManager extensionManager) { - _siteService = siteService; + public AntiForgeryAuthorizationFilter(IAuthenticationService authenticationService, IExtensionManager extensionManager) { _authenticationService = authenticationService; _extensionManager = extensionManager; } public void OnAuthorization(AuthorizationContext filterContext) { + // If the request is not a POST or is anonymous, and the request doesn't have validation forced, return. if ((filterContext.HttpContext.Request.HttpMethod != "POST" || _authenticationService.GetAuthenticatedUser() == null) && !ShouldValidateGet(filterContext)) { return; @@ -39,20 +38,19 @@ namespace Orchard.Mvc.AntiForgery { filterContext.HttpContext = ((HackHttpContext)filterContext.HttpContext).OriginalHttpContextBase; } - private bool IsAntiForgeryProtectionEnabled(ControllerContext context) { - string currentModule = GetArea(context.RouteData); - if (!String.IsNullOrEmpty(currentModule)) { - foreach (var descriptor in _extensionManager.AvailableExtensions()) { - if (String.Equals(descriptor.Id, currentModule, StringComparison.OrdinalIgnoreCase)) { - if (String.Equals(descriptor.AntiForgery, "enabled", StringComparison.OrdinalIgnoreCase)) { - return true; - } - return false; - } - } - } + private bool IsAntiForgeryProtectionEnabled(AuthorizationContext context) { + // POST is opt-out + var attributes = + (ValidateAntiForgeryTokenOrchardAttribute[]) + context.ActionDescriptor.GetCustomAttributes(typeof (ValidateAntiForgeryTokenOrchardAttribute), false); - return false; + if (attributes.Length > 0 && !attributes[0].Enabled) return false; + + var currentModule = GetArea(context.RouteData); + return !String.IsNullOrEmpty(currentModule) + && (_extensionManager.AvailableExtensions() + .First(descriptor => String.Equals(descriptor.Id, currentModule, StringComparison.OrdinalIgnoreCase)) + .AntiForgery.Equals("enabled", StringComparison.OrdinalIgnoreCase)); } private static string GetArea(RouteData routeData) { @@ -69,7 +67,7 @@ namespace Orchard.Mvc.AntiForgery { (ValidateAntiForgeryTokenOrchardAttribute[]) context.ActionDescriptor.GetCustomAttributes(typeof (ValidateAntiForgeryTokenOrchardAttribute), false); - if (attributes.Length > 0) { + if (attributes.Length > 0 && attributes[0].Enabled) { var request = context.HttpContext.Request; //HAACK: (erikpo) If the token is in the querystring, put it in the form so MVC can validate it diff --git a/src/Orchard/Mvc/AntiForgery/ValidateAntiForgeryTokenOrchardAttribute.cs b/src/Orchard/Mvc/AntiForgery/ValidateAntiForgeryTokenOrchardAttribute.cs index d1a5a688c..3230ca5c9 100644 --- a/src/Orchard/Mvc/AntiForgery/ValidateAntiForgeryTokenOrchardAttribute.cs +++ b/src/Orchard/Mvc/AntiForgery/ValidateAntiForgeryTokenOrchardAttribute.cs @@ -4,5 +4,14 @@ using System.Web.Mvc; namespace Orchard.Mvc.AntiForgery { [AttributeUsage(AttributeTargets.Method)] public class ValidateAntiForgeryTokenOrchardAttribute : FilterAttribute { + private readonly bool _enabled = true; + + public ValidateAntiForgeryTokenOrchardAttribute() : this(true) {} + + public ValidateAntiForgeryTokenOrchardAttribute(bool enabled) { + _enabled = enabled; + } + + public bool Enabled { get { return _enabled; } } } } \ No newline at end of file