Why can't I combine [Authorize] and [OutputCache] attributes when using Azure cache (.NET MVC3 app)?

前端 未结 3 1332
遇见更好的自我
遇见更好的自我 2020-12-01 11:15

Using Windows Azure\'s Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider as the outputCache provider for an MVC3 app. Here is the relevant acti

3条回答
  •  情深已故
    2020-12-01 11:37

    Caching happens before the Action. You will likely need to customize your authorization mechanics to handle cache scenarios.

    Check out a question I posted a while back - MVC Custom Authentication, Authorization, and Roles Implementation.

    The part I think would help you is a custom Authorize Attribute who's OnAuthorize() method deals with caching.

    Below is a code block for example:

    /// 
    /// Uses injected authorization service to determine if the session user 
    /// has necessary role privileges.
    /// 
    /// As authorization code runs at the action level, after the 
    /// caching module, our authorization code is hooked into the caching 
    /// mechanics, to ensure unauthorized users are not served up a 
    /// prior-authorized page. 
    /// Note: Special thanks to TheCloudlessSky on StackOverflow.
    /// 
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // User must be authenticated and Session not be null
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated || filterContext.HttpContext.Session == null)
            HandleUnauthorizedRequest(filterContext);
        else {
            // if authorized, handle cache validation
            if (_authorizationService.IsAuthorized((UserSessionInfoViewModel)filterContext.HttpContext.Session["user"], _authorizedRoles)) {
                var cache = filterContext.HttpContext.Response.Cache;
                cache.SetProxyMaxAge(new TimeSpan(0));
                cache.AddValidationCallback((HttpContext context, object o, ref HttpValidationStatus status) => AuthorizeCache(context), null);
            }
            else
                HandleUnauthorizedRequest(filterContext);             
        }
    }
    
    /// 
    /// Ensures that authorization is checked on cached pages.
    /// 
    /// 
    /// 
    public HttpValidationStatus AuthorizeCache(HttpContext httpContext)
    {
        if (httpContext.Session == null)
            return HttpValidationStatus.Invalid;
        return _authorizationService.IsAuthorized((UserSessionInfoViewModel) httpContext.Session["user"], _authorizedRoles) 
            ? HttpValidationStatus.Valid 
            : HttpValidationStatus.IgnoreThisRequest;
    }
    

提交回复
热议问题