是否可以在 ASP.NET MVC & Identity 2.0 中缓存授权?

Is it possible to cache authorizations in ASP.NET MVC & Identity 2.0?

如果这个问题不知何故 off-topic,请告诉我。 我会把它带到别处,但我想获得一些关于如何在现有项目中完成某些事情的想法。

我的网络应用程序(使用 ASP.NET MVC 5 和 ASP.NET Identity 2.0)使用自定义角色提供程序执行授权(通过那些花哨的 Authorize 属性)。 每个授权检查(如 Authorize(Roles = "Admin"))都需要查询数据库以执行以下操作:

如果记录存在,则用户被授权,否则他们不是。 需要明确的是,分配给一个角色与一个学期相关联,以便将相应的特权限制在一个学期的持续时间内。 也就是说,一旦学期结束,用户不再拥有他们的权力,但下学期任命的下一个人将立即获得他们的权力。

我的大多数用户都属于在他们访问的绝大多数页面上都经过检查的角色,但不是全部。 每次我需要授权时,都会执行所有这些步骤。

为了清楚起见,这里有一张数据库图片:

有没有办法缓存(这样我就不用经常查询数据库)这些授权的时间长度相当于从第一次检查performed/cached到结束的时间学期的? 或者只是在任何合理的时间内缓存它们? 理想情况下,如果一个学期或职位因任何原因更新,授权将以某种方式无效并且 re-cached。 最后,自定义 RoleProvider 是解决此问题的可靠方法吗?

Is there a way to cache (so that I don't have to constantly query the database) these authorizations for a length of time equivalent to the time from when the check is first performed/cached to the end of the semester?

默认情况下,ASP.Net身份在用户成功登录后将用户的授权角色存储在Role Claim中。这些声明存储在 cookie 中,直到用户注销或关闭浏览器。

不值得为授权属性实施额外的缓存。

我会小心缓存授权本身。您想保持灵活性,如果不仔细设计,您很容易在应用程序中发现安全漏洞。

但是,您为获取用于做出授权决定的信息而进行的查询可能会被缓存。为此,我建议使用 MemoryCache。只需:

ObjectCache cache = MemoryCache.Default;

...

var foos = cache.Get("key") as List<Foo>;
if (foos == null)
{
    foos = repo.GetFoos();
    cache.Add("key", foos, new CacheItemPolicy
    { 
        AbsoluteExpiration = DateTimeOffset.Now.AddHours(1)
    });
}

// do something with `foos`

这基本上就是它的工作原理,但是在网络这样的环境中,您需要考虑并发性。我写了一个post on my blog,它提供了一个扩展,使处理这个问题变得容易得多。