mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-23 04:43:35 +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.Services;
|
||||||
using Orchard.Core.Navigation.ViewModels;
|
using Orchard.Core.Navigation.ViewModels;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
|
using Orchard.Mvc.Attributes;
|
||||||
using Orchard.UI.Navigation;
|
using Orchard.UI.Navigation;
|
||||||
using Orchard.Utility;
|
using Orchard.Utility;
|
||||||
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
|
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
|
||||||
@@ -100,7 +101,7 @@ namespace Orchard.Core.Navigation.Controllers {
|
|||||||
return RedirectToAction("Index");
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
//[ValidateAntiForgeryTokenOrchard]
|
[ValidateAntiForgeryTokenOrchard]
|
||||||
public ActionResult Delete(int id) {
|
public ActionResult Delete(int id) {
|
||||||
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
|
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
@@ -37,6 +37,8 @@ namespace Orchard.Web {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void Application_BeginRequest() {
|
protected void Application_BeginRequest() {
|
||||||
|
Context.Items["originalHttpContext"] = Context;
|
||||||
|
|
||||||
_host.BeginRequest();
|
_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 System.Web.Mvc;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Orchard.Mvc.Attributes;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
using Orchard.Settings;
|
using Orchard.Settings;
|
||||||
|
|
||||||
@@ -15,17 +18,99 @@ namespace Orchard.Mvc.Filters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void OnAuthorization(AuthorizationContext filterContext) {
|
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;
|
return;
|
||||||
|
}
|
||||||
// not logged in: no attack vector
|
|
||||||
if (_authenticationService.GetAuthenticatedUser() == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var siteSalt = _siteService.GetSiteSettings().SiteSalt;
|
var siteSalt = _siteService.GetSiteSettings().SiteSalt;
|
||||||
var validator = new ValidateAntiForgeryTokenAttribute { Salt = siteSalt };
|
var validator = new ValidateAntiForgeryTokenAttribute {Salt = siteSalt};
|
||||||
validator.OnAuthorization(filterContext);
|
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\ExtensionFolders.cs" />
|
||||||
<Compile Include="Extensions\Loaders\AreaExtensionLoader.cs" />
|
<Compile Include="Extensions\Loaders\AreaExtensionLoader.cs" />
|
||||||
<Compile Include="Extensions\UriExtensions.cs" />
|
<Compile Include="Extensions\UriExtensions.cs" />
|
||||||
|
<Compile Include="Mvc\Attributes\ValidateAntiForgeryTokenOrchardAttribute.cs" />
|
||||||
<Compile Include="OrchardException.cs" />
|
<Compile Include="OrchardException.cs" />
|
||||||
<Compile Include="Security\IAuthorizationServiceEvents.cs" />
|
<Compile Include="Security\IAuthorizationServiceEvents.cs" />
|
||||||
<Compile Include="Security\StandardPermissions.cs" />
|
<Compile Include="Security\StandardPermissions.cs" />
|
||||||
|
Reference in New Issue
Block a user