Actions can opt out of anti-forgery by adding [AntiForgeryTokenOrchard(false)]

This commit is contained in:
Bertrand Le Roy
2014-10-14 17:19:38 -07:00
parent 507ddd13b8
commit 314f9a4e18
2 changed files with 25 additions and 18 deletions

View File

@@ -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

View File

@@ -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; } }
}
}