Tyler Morrow
Tyler Morrow

Reputation: 961

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

if this question is somehow off-topic, let me know. I will take it elsewhere, but I wanted to get some ideas on how to accomplish something within an existing project.

My web app (using ASP.NET MVC 5 and ASP.NET Identity 2.0) performs authorization (via those fancy Authorize attributes) with a custom Role Provider. Every authorization check (like Authorize(Roles = "Admin")) requires querying the database to perform the following:

If a record exists, the user is authorized, otherwise they are not. To be clear, assignment to a role is tied to a semester in order to limit the corresponding privileges to the duration of a semester. I.e., once the semester ends, the user no longer has their powers, but the next person appointed for the next semester will immediately gain theirs.

Most of my users fall into roles that are checked on a great majority of the pages they visit, but not all. All of those steps are performed, every time I need to authorize.

Here is an image of the database just to make it clear: enter image description here

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? Or just cache them at all for any amount of time that's reasonable? Ideally, if a semester or position is updated for whatever reason, the authorizations would somehow be made invalid and re-cached. Lastly, is a custom RoleProvider a solid way to go about this?

Upvotes: 0

Views: 2610

Answers (2)

Chris Pratt
Chris Pratt

Reputation: 239220

I'd be careful of caching the authorization, itself. You want to remain flexible with that, and without careful design, you can easily poke security holes in your application.

However, the queries you're making to get the information that is used to make the authorized determination could be potentially cached. For that, I'd recommend using MemoryCache. Simply:

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`

That's basically how it works, but in an environment like the web, you need to think about concurrency. I wrote a post on my blog that provides an extension to make handling this a lot easier.

Upvotes: 1

Win
Win

Reputation: 62260

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?

By default, ASP.Net Identity stores user's authorized roles inside Role Claim after user successful login. Those claims are stored inside cookie until user logout or close the browser.

It is not worth implementing additional caching for authorize attribute.

Upvotes: 3

Related Questions