自定义授权属性

时间:2011-03-05 18:34:05

标签: asp.net-mvc authorization

我正在实现CustomAuthorizeAttribute。我需要获取正在执行的操作的名称。如何在AuthorizeCore函数中获取当前操作名称的名称?我将重写该文件?

2 个答案:

答案 0 :(得分:5)

如果您正在使用缓存(或有计划),那么覆盖AuthorizeCore,就像Darin Dimitrov在this answer中显示的那样是一个更安全的选择:

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    var routeData = httpContext.Request.RequestContext.RouteData;
    var controller = routeData.GetRequiredString("controller");
    var action = routeData.GetRequiredString("action");
    ...
}

MVC source code本身记录了这个原因:

AuthorizeAttribute.cs (第72-101行)

public virtual void OnAuthorization(AuthorizationContext filterContext) {
    if (filterContext == null) {
        throw new ArgumentNullException("filterContext");
    }

    if (OutputCacheAttribute.IsChildActionCacheActive(filterContext)) {
        // If a child action cache block is active, we need to fail immediately, even if authorization
        // would have succeeded. The reason is that there's no way to hook a callback to rerun
        // authorization before the fragment is served from the cache, so we can't guarantee that this
        // filter will be re-run on subsequent requests.
        throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
    }

    if (AuthorizeCore(filterContext.HttpContext)) {
        // ** IMPORTANT **
        // Since we're performing authorization at the action level, the authorization code runs
        // after the output caching module. In the worst case this could allow an authorized user
        // to cause the page to be cached, then an unauthorized user would later be served the
        // cached page. We work around this by telling proxies not to cache the sensitive page,
        // then we hook our custom authorization code into the caching mechanism so that we have
        // the final say on whether a page should be served from the cache.

        HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
        cachePolicy.SetProxyMaxAge(new TimeSpan(0));
        cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
    }
    else {
        HandleUnauthorizedRequest(filterContext);
    }
}

即使你没有计划使用缓存,这两个神奇的字符串似乎是一个很小的代价,可以让你得到回报的安心(以及你自己保存的潜在麻烦。)如果你仍想覆盖{ {1}}相反,您应该至少确保不缓存请求。有关更多背景信息,请参阅Levi的this post

答案 1 :(得分:2)

您可以像这样获取动作名称:

public class CustomAuthFilter : IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            filterContext.ActionDescriptor.ActionName;
        }
    }

编辑:

如果要继承AuthorizationAttribute,则需要覆盖OnAuthorization方法。

public class CustomAuthAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }
}