asp.Net   发布时间:2022-04-07  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了asp.net-mvc-3 – 为什么在使用Azure缓存(.NET MVC3应用程序)时无法组合[Authorize]和[OutputCache]属性?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
使用Windows Azure的Microsoft.Web.DiStributedCache.DiStributedCacheOutputCacheProvider作为MVC3应用程序的outputCache提供程序。以下是相关的操作方法:
[ActionName("sample-cached-page")]
[OutputCache(Duration = 300,VaryByCustom = "User",LOCATIOn = OutputCacheLOCATIOn.Server)]
[Authorize(Users = "me@mydomain.tld,another@otherdomain.tld")]
public virtual ActionResult SampleCachedPage()
{
    return View();
}

从Web浏览器加载此视图时,我会收到以下异常:

System.Configuration.Provider.ProviderException: When using a custom output cache provider like 'DiStributedCache',only the following expiration policies and cache features are supported: file dependencies,absolute expirations,static validation callBACks and static substitution callBACks.

System.Configuration.Provider.ProviderException: When using a custom output cache provider like 'DiStributedCache',only the following expiration policies and cache features are supported:  file dependencies,static validation callBACks and static substitution callBACks.
   at System.Web.Caching.outputCache.InsertResponse(String cachedVaryKey,CachedVary cachedVary,String rawResponseKey,CachedRawResponse rawResponse,CacheDependency dependencies,datetiR_785_11845@e absExp,TimeSpan slidingExp)
   at System.Web.Caching.outputCacheModule.onLeave(Object source,EventArgs eventArgs)
   at System.Web.httpApplication.SyncEventEXECUTIONStep.System.Web.httpApplication.IEXECUTIONStep.Execute()
   at System.Web.httpApplication.ExecuteStep(IEXECUTIONStep step,Boolean& completedSynchronously)

如果我删除[Authorize]属性,视图将按预期缓存。这是否意味着我不能将[OutputCache]放在必须具有[授权]的操作方法上?或者,是否需要使用为缓存使用静态验证回调方法的自定义实现来覆盖AuthorizeAttribute?

更新1

在Evan的答案之后,我在IIS Express(Azure外)测试了上述动作方法。以下是对OutputCache属性的VaryByCustom =“User”属性的覆盖:

public override String GetVaryByCustomString(httpContext context,String custom)
{
    return "User".Equals(custom,StringComparison.ordinalIgnoreCasE)
        ? Thread.CurrentPrincipal.Identity.Name
        : base.GetVaryByCustomString(context,custom);
}

当我访问示例缓存页面为me@mydomain.tld时,该页面的输出被缓存,视图显示“此页被缓存在12/31/2011 11:06:12 AM(UTC)”。如果我以login@otherdomain.tld身份登录并登录,请访问该页面,显示“此页面缓存于12/31/2011 11:06:38 AM(UTC)”。重新登录为me@mydomain.tld并重新访问页面将导致缓存显示“此页面被缓存在12/31/2011 11:06:12 AM(UTC)”。进一步登录/尝试显示不同的输出正在被缓存根据用户返回。

这导致我相信输出是基于用户单独缓存的,这是我的VaryByCustom =“用户”设置&覆盖。问题是它不适用于Azure的分布式缓存提供程序。埃文,你是否回答只有缓存公开的内容呢还是站立的?

更新2

我挖出了源代码,发现开箱即用的AuthorizeAttribute实际上有一个非静态的验证回调函数。以下是OnAuthorization的摘录:

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);
}

CacheValidationHandler将缓存验证委托给受保护的虚拟httpValidationStatus OnCacheAuthorization(httpContextBasE),这当然不是静态的。它不是静态的一个原因是因为,如上面的重要注释中所述,它调用受保护的虚拟bool AuthorizeCore(httpContextBasE)

为了从静态缓存验证回调方法中执行任何AuthorizeCore逻辑,它需要知道AuthorizeAttribute实例的Users和Roles属性。但是,似乎并没有一个简单的方法来插入。我必须重写OnAuthorization以将这两个值放入httpContext(Items集合?)中,然后覆盖OnCacheAuthorization以使它们退出。但是闻起来很脏

如果我们小心地使用OutputCache属性中的VaryByCustom =“User”属性,那么我们只能覆盖OnCacheAuthorization来始终返回httpValidationStatus.Valid?当action方法没有OutputCache属性时,我们不需要担心这个回调被调用是正确的吗?如果我们有一个没有VaryByCustom =“User”的OutputCache属性,那么显而易见的是,页面可以返回任何缓存的版本,而不管用户的请求是创建缓存的副本。这有多风险?

解决方法

缓存发生在Action之前。您可能需要自定义您的授权机制来处理缓存方案。

查看我发布的一个问题 – MVC Custom Authentication,Authorization,and Roles Implementation

我认为这将帮助您的一部分是OnAuthorize()方法处理缓存的自定义授权属性。

以下是一个代码块,例如:

/// <sumMary>
/// Uses injected authorization service to determine if the session user 
/// has necessary role privileges.
/// </sumMary>
/// <REMARKs>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.
/// </REMARKs>
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);             
    }
}

/// <sumMary>
/// Ensures that authorization is checked on cached pages.
/// </sumMary>
/// <param name="httpContext"></param>
/// <returns></returns>
public httpValidationStatus AuthorizeCache(httpContext httpContext)
{
    if (httpContext.Session == null)
        return httpValidationStatus.Invalid;
    return _authorizationservice.IsAuthorized((UserSessionInfoViewModel) httpContext.Session["user"],_authorizedRoles) 
        ? httpValidationStatus.Valid 
        : httpValidationStatus.IgnoreThisrequest;
}

大佬总结

以上是大佬教程为你收集整理的asp.net-mvc-3 – 为什么在使用Azure缓存(.NET MVC3应用程序)时无法组合[Authorize]和[OutputCache]属性?全部内容,希望文章能够帮你解决asp.net-mvc-3 – 为什么在使用Azure缓存(.NET MVC3应用程序)时无法组合[Authorize]和[OutputCache]属性?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。