renamed to MemberAuthorizeAttribute and changed it to inherit from a AuthorizeAttribute as this happens much further up the chain than

the filter attribute and also contains the correct logic to ensure authorization always happens regardless of if the page is cached. Cleaned
up our other authorize attibutes.
This commit is contained in:
Shannon Deminick
2013-02-26 02:21:51 +06:00
parent 2967075c1f
commit db268c6805
4 changed files with 45 additions and 77 deletions

View File

@@ -2,6 +2,7 @@ using System;
using System.Web;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Web.Security;
using umbraco.BasePages;
namespace Umbraco.Web.Install
@@ -33,12 +34,9 @@ namespace Umbraco.Web.Install
/// <returns></returns>
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
if (httpContext == null) throw new ArgumentNullException("httpContext");
try
try
{
//if its not configured then we can continue
if (!_applicationContext.IsConfigured)
@@ -47,7 +45,7 @@ namespace Umbraco.Web.Install
}
//otherwise we need to ensure that a user is logged in
var isLoggedIn = BasePage.ValidateUserContextID(BasePage.umbracoUserContextID);
var isLoggedIn = WebSecurity.ValidateUserContextId(WebSecurity.UmbracoUserContextId);
if (isLoggedIn)
{
return true;
@@ -60,30 +58,16 @@ namespace Umbraco.Web.Install
return false;
}
}
/// <summary>
/// Override to throw exception instead of returning 401 result
/// </summary>
/// <param name="filterContext"></param>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//they aren't authorized but the app has installed
throw new HttpException((int)global::System.Net.HttpStatusCode.Unauthorized, "You must login to view this resource.");
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
Mandate.ParameterNotNull(filterContext, "filterContext");
if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
throw new InvalidOperationException("Cannot use UmbracoInstallAuthorizeAttribute on a child action");
if (AuthorizeCore(filterContext.HttpContext))
{
//with a little help from dotPeek... this is what it normally would do
var cache = filterContext.HttpContext.Response.Cache;
cache.SetProxyMaxAge(new TimeSpan(0L));
cache.AddValidationCallback(CacheValidateHandler, null);
}
else
{
//they aren't authorized but the app has installed
throw new HttpException((int)global::System.Net.HttpStatusCode.Unauthorized,
"You must login to view this resource.");
}
}
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
}
}

View File

@@ -1,16 +1,18 @@
using System.Linq;
using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Umbraco.Core;
using umbraco.cms.businesslogic.member;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// "Base-like" attribute for attributing surface controller actions to restrict them
/// Attribute for attributing controller actions to restrict them
/// to just authenticated members, and optionally of a particular type and/or group
/// </summary>
public class SurfaceAuthorizeAttribute : ActionFilterAttribute
public class MemberAuthorizeAttribute : AuthorizeAttribute
{
/// <summary>
/// Flag for whether to allow all site visitors or just authenticated members
@@ -32,10 +34,10 @@ namespace Umbraco.Web.Mvc
/// </summary>
public string AllowMembers { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// Allow by default
bool allowAction = true;
var allowAction = true;
// If not set to allow all, need to check current loggined in member
if (!AllowAll)
@@ -60,7 +62,7 @@ namespace Umbraco.Web.Mvc
if (allowAction && !string.IsNullOrEmpty(AllowGroup))
{
// Allow only if member's type is in list
var groups = Roles.GetRolesForUser(member.LoginName);
var groups = System.Web.Security.Roles.GetRolesForUser(member.LoginName);
allowAction = groups.Select(s => s.ToLower()).Intersect(AllowGroup.ToLower().Split(',')).Any();
}
@@ -72,12 +74,17 @@ namespace Umbraco.Web.Mvc
}
}
}
// If not allowed, throw 403 exception
if (!allowAction)
{
throw new HttpException(403, "Resource restricted: either member is not logged on or is not of a permitted type or group.");
}
return allowAction;
}
/// <summary>
/// Override method to throw exception instead of returning a 401 result
/// </summary>
/// <param name="filterContext"></param>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
throw new HttpException(403, "Resource restricted: either member is not logged on or is not of a permitted type or group.");
}
}
}

View File

@@ -34,12 +34,9 @@ namespace Umbraco.Web.Mvc
/// <returns></returns>
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
try
if (httpContext == null) throw new ArgumentNullException("httpContext");
try
{
//we need to that the app is configured and that a user is logged in
if (!_applicationContext.IsConfigured)
@@ -53,32 +50,14 @@ namespace Umbraco.Web.Mvc
}
}
/// <summary>
/// Override the OnAuthorization so that we can return a custom response.
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
Mandate.ParameterNotNull(filterContext, "filterContext");
if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
throw new InvalidOperationException("Cannot use " + typeof(UmbracoAuthorizeAttribute).FullName + " on a child action");
if (AuthorizeCore(filterContext.HttpContext))
{
//with a little help from dotPeek... this is what it normally would do
var cache = filterContext.HttpContext.Response.Cache;
cache.SetProxyMaxAge(new TimeSpan(0L));
cache.AddValidationCallback(CacheValidateHandler, null);
}
else
{
//they aren't authorized
throw new HttpException((int)global::System.Net.HttpStatusCode.Unauthorized, "You must login to view this resource.");
}
}
/// <summary>
/// Override to throw exception instead of returning a 401 result
/// </summary>
/// <param name="filterContext"></param>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
throw new HttpException((int)global::System.Net.HttpStatusCode.Unauthorized, "You must login to view this resource.");
}
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
}
}

View File

@@ -319,11 +319,9 @@
<Compile Include="DefaultPublishedMediaStore.cs" />
<Compile Include="Dictionary\UmbracoCultureDictionary.cs" />
<Compile Include="Dictionary\UmbracoCultureDictionaryFactory.cs" />
<Compile Include="Mvc\SurfaceAuthorizeAttribute.cs">
<SubType>Code</SubType>
<Compile Include="Mvc\MemberAuthorizeAttribute.cs" />
<Compile Include="Mvc\ControllerFactoryExtensions.cs" />
<Compile Include="Mvc\SurfaceRouteHandler.cs" />
</Compile>
<Compile Include="Mvc\UmbracoAuthorizeAttribute.cs" />
<Compile Include="Mvc\UmbracoAuthorizedController.cs" />
<Compile Include="Mvc\UmbracoController.cs" />