自定义授权属性

Sun*_*ban 2 asp.net-mvc authorization

我正在实现CustomAuthorizeAttribute.我需要获取正在执行的操作的名称.如何在AuthorizeCore函数中获取当前操作名称的名称?

Dan*_*zzi 5

如果你正在使用缓存(或有计划),那么覆盖AuthorizeCore,如Darin Dimitrov在这个答案中显示的是一个更安全的赌注:

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

其原因记录在MVC源代码本身中:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

即使你没有计划使用缓存,这两个神奇的字符串似乎是一个很小的代价,让你得到回报的安心(以及你自己保存的潜在头痛.)如果你仍然想要覆盖OnAuthorization,你应该至少确保请求没有缓存.有关更多背景信息,请参阅Levi的这篇文章.