mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-22 20:13:50 +08:00
Added some hacks to get http get calls to be validated when an attribute exists on a controller action
--HG-- branch : dev
This commit is contained in:
@@ -8,6 +8,7 @@ using Orchard.Core.Navigation.Models;
|
||||
using Orchard.Core.Navigation.Services;
|
||||
using Orchard.Core.Navigation.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc.Attributes;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.Utility;
|
||||
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
|
||||
@@ -100,7 +101,7 @@ namespace Orchard.Core.Navigation.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
//[ValidateAntiForgeryTokenOrchard]
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
public ActionResult Delete(int id) {
|
||||
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
@@ -37,6 +37,8 @@ namespace Orchard.Web {
|
||||
}
|
||||
|
||||
protected void Application_BeginRequest() {
|
||||
Context.Items["originalHttpContext"] = Context;
|
||||
|
||||
_host.BeginRequest();
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Mvc.Attributes {
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ValidateAntiForgeryTokenOrchardAttribute : FilterAttribute {
|
||||
}
|
||||
}
|
@@ -1,5 +1,8 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Mvc.Attributes;
|
||||
using Orchard.Security;
|
||||
using Orchard.Settings;
|
||||
|
||||
@@ -15,17 +18,99 @@ namespace Orchard.Mvc.Filters {
|
||||
}
|
||||
|
||||
public void OnAuthorization(AuthorizationContext filterContext) {
|
||||
// not a post: no work to do
|
||||
if (filterContext.HttpContext.Request.HttpMethod != "POST")
|
||||
if ((filterContext.HttpContext.Request.HttpMethod != "POST" ||
|
||||
_authenticationService.GetAuthenticatedUser() == null) && !ShouldValidateGet(filterContext)) {
|
||||
return;
|
||||
|
||||
// not logged in: no attack vector
|
||||
if (_authenticationService.GetAuthenticatedUser() == null)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var siteSalt = _siteService.GetSiteSettings().SiteSalt;
|
||||
var validator = new ValidateAntiForgeryTokenAttribute { Salt = siteSalt };
|
||||
var validator = new ValidateAntiForgeryTokenAttribute {Salt = siteSalt};
|
||||
validator.OnAuthorization(filterContext);
|
||||
|
||||
if (filterContext.HttpContext is HackHttpContext)
|
||||
filterContext.HttpContext = ((HackHttpContext)filterContext.HttpContext).OriginalHttpContextBase;
|
||||
}
|
||||
|
||||
private static bool ShouldValidateGet(AuthorizationContext context) {
|
||||
const string tokenFieldName = "__RequestVerificationToken";
|
||||
|
||||
var attributes =
|
||||
(ValidateAntiForgeryTokenOrchardAttribute[])
|
||||
context.ActionDescriptor.GetCustomAttributes(typeof (ValidateAntiForgeryTokenOrchardAttribute), false);
|
||||
|
||||
if (attributes.Length > 0) {
|
||||
var request = context.HttpContext.Request;
|
||||
|
||||
//HAACK: (erikpo) If the token is in the querystring, put it in the form so MVC can validate it
|
||||
if (!string.IsNullOrEmpty(request.QueryString[tokenFieldName])) {
|
||||
context.HttpContext = new HackHttpContext(context.HttpContext, (HttpContext)context.HttpContext.Items["originalHttpContext"]);
|
||||
((HackHttpRequest)context.HttpContext.Request).AddFormValue(tokenFieldName, context.HttpContext.Request.QueryString[tokenFieldName]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#region HackHttpContext
|
||||
|
||||
private class HackHttpContext : HttpContextWrapper {
|
||||
private readonly HttpContextBase _originalHttpContextBase;
|
||||
private readonly HttpContext _originalHttpContext;
|
||||
private HttpRequestWrapper _request;
|
||||
|
||||
public HackHttpContext(HttpContextBase httpContextBase, HttpContext httpContext)
|
||||
: base(httpContext) {
|
||||
_originalHttpContextBase = httpContextBase;
|
||||
_originalHttpContext = httpContext;
|
||||
}
|
||||
|
||||
public HttpContextBase OriginalHttpContextBase {
|
||||
get { return _originalHttpContextBase; }
|
||||
}
|
||||
|
||||
public override HttpRequestBase Request
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_request == null)
|
||||
_request = new HackHttpRequest(_originalHttpContext.Request);
|
||||
|
||||
return _request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region HackHttpRequest
|
||||
|
||||
private class HackHttpRequest : HttpRequestWrapper {
|
||||
private readonly HttpRequest _originalHttpRequest;
|
||||
private NameValueCollection _form;
|
||||
|
||||
public HackHttpRequest(HttpRequest httpRequest)
|
||||
: base(httpRequest) {
|
||||
_originalHttpRequest = httpRequest;
|
||||
}
|
||||
|
||||
public override NameValueCollection Form
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_form == null)
|
||||
_form = new NameValueCollection(_originalHttpRequest.Form);
|
||||
|
||||
return _form;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddFormValue(string key, string value) {
|
||||
Form.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -151,6 +151,7 @@
|
||||
<Compile Include="Extensions\ExtensionFolders.cs" />
|
||||
<Compile Include="Extensions\Loaders\AreaExtensionLoader.cs" />
|
||||
<Compile Include="Extensions\UriExtensions.cs" />
|
||||
<Compile Include="Mvc\Attributes\ValidateAntiForgeryTokenOrchardAttribute.cs" />
|
||||
<Compile Include="OrchardException.cs" />
|
||||
<Compile Include="Security\IAuthorizationServiceEvents.cs" />
|
||||
<Compile Include="Security\StandardPermissions.cs" />
|
||||
|
Reference in New Issue
Block a user