Azure AD认证Web应用因OutputCache与Authorize致用户信息显示错误求助
这个问题的核心是默认的OutputCache不会区分登录用户——当第一个用户访问带[OutputCache]的页面时,页面内容(包括用户身份信息)会被缓存下来,后续其他用户访问时,服务器直接返回缓存的旧页面,自然会显示之前用户的信息。下面是几种可行的解决办法:
1. 让OutputCache按用户生成独立缓存项
给[OutputCache]添加VaryByCustom="user"参数,然后在项目的Global.asax文件中重写GetVaryByCustomString方法,用当前用户的唯一标识(比如邮箱或Azure AD的ObjectId)作为缓存区分依据:
控制器代码:
[OutputCache(Duration = 3600, VaryByCustom = "user")] [Authorize] public ActionResult Index() { return View(); }
Global.asax代码:
public override string GetVaryByCustomString(HttpContext context, string custom) { if (custom.Equals("user", StringComparison.OrdinalIgnoreCase)) { // 返回当前登录用户的唯一标识,这里用邮箱示例 return context.User.Identity.Name; } // 其他自定义缓存规则交给基类处理 return base.GetVaryByCustomString(context, custom); }
这样每个用户访问时都会生成独立的缓存副本,不会互相干扰。
2. 拆分缓存范围,只缓存非个性化内容
如果页面大部分内容是公共的,只有用户信息区域是个性化的,把用户信息单独抽成局部视图,不对整个页面缓存,只缓存公共部分:
主视图中调用非缓存的用户信息局部视图:
<!-- 这部分公共内容可以单独加缓存 --> <div class="public-content"> <!-- 公共内容 --> </div> <!-- 用户信息区域调用不缓存的Action --> @Html.Action("RenderUserInfo", "Account")
Account控制器代码:
[Authorize] // 这里不要加OutputCache,确保每次请求都获取当前用户信息 public ActionResult RenderUserInfo() { return PartialView("_UserInfo"); }
3. 基于认证请求头区分缓存
如果你的应用用的是Bearer Token认证(Azure AD通常是这种),可以让OutputCache根据Authorization请求头来区分缓存项,每个用户的Token不同,缓存自然独立:
[OutputCache(Duration = 3600, VaryByHeader = "Authorization")] [Authorize] public ActionResult Index() { return View(); }
注意:这种方式会生成大量缓存项(每个用户一个),如果用户量很大,可能会占用较多服务器资源,需要根据实际情况权衡。
4. 直接移除页面的OutputCache属性
如果页面本身个性化程度高,不需要缓存,直接去掉[OutputCache]属性,彻底避免缓存冲突。
内容的提问来源于stack exchange,提问作者Kurkula
相关产品推荐
相关产品推荐

