Using ASP.NET MVC OutputCache while varying View content based on whether user is authenticated
Asked Answered
S

2

6

I'm building an ASP.NET MVC 2 site where I'm using the OutputCache parameter heavily. However, I have a concern: using such caching may interfere with authentication.

On all of my pages, I display whether the user is logged in or not. Furthermore, in some of my Views, I do filtering based on user role to determine whether or not to display some page content (for example, the Edit link on one of my pages is only shown to users in the roles of Moderator or Administrator).

Will using OutputCache interfere with this dynamic changing of my Views? If so, how can I resolve this problem without eliminating caching?

Seymore answered 9/8, 2010 at 21:11 Comment(0)
S
9

The [OutputCache] and [Authorize] attributes play well with one another. The AuthorizeAttribute.OnAuthorization() method sets a hook into the output caching system that forces the authorization filter to re-run before the page is served from the cache. If the authorization filter logic fails, it will be treated as a cache miss. If the authorization logic succeeds, the page will be served from the cache. So if you have [Authorize(Roles = "Moderator, Administrator")] and [OutputCache] on an action, the page will not be served from the cache unless the current user is in the Moderator or Administrator roles.

Note that this does not vary by user or role; it's literally re-running the original check. Imagine that User A (who is a Moderator) comes in and causes the page to be cached. Now User B (who is an Administrator) comes in and hits the cached page. The [Authorize] check will succeed since both Administrator and Moderator are allowed, and the response served to User B will contain the exact same contents as the response that was served to User A.

Note that response substitution does not work in MVC 2. If you're serving potentially sensitive data, the best bet here is not to cache it. If you absolutely need to cache, you can mimic something similar to response substitution by using an AJAX callback to dynamically fill in the missing data.

Surtout answered 9/8, 2010 at 21:47 Comment(5)
What if I have a method that doesn't require authorization but adds an Edit link inside the View if the user is a moderator? In this case, I'm trying to accomplish something that resembles how the link, flag, edit, and other buttons under a question or answer here work - doesn't SO use OutputCache, too? Thanks for your answer!Seymore
I just stumbled across blog.stevensanderson.com/2008/10/15/… (about an old problem that was later fixed), which gave me an idea - if OutputCache is so bad with this, is it possible to build a custom caching attribute/filter that creates different copies based on whether the user is logged-in and what roles the user is in - or better yet, what the username is, as I'm going to write the name of the user at the top of the page - is that possible?Seymore
It's generally a bad idea to cache per-user, as your cache is going to be flooded with entries. If donut caching is important to your scenario, you could also use a response filter. At the beginning of the request, install a filter that understands some [!! SUBSTITUTION DATA !!] pattern, have your WriteSubstitute() write this pattern to the response stream, then at the end of the request your filter would call into the actual Response.WriteSubstitution() method.Surtout
To answer your question re: varying by pretty much anything (including username), see aspadvice.com/blogs/ssmith/archive/2007/10/29/… and msdn.microsoft.com/en-us/library/…. Remember though that this is not recommended.Surtout
I ended up completely cutting caching for authenticated users on the advice of Jeff Atwood at meta.stackexchange.com/questions/60403/…Seymore
C
1

I believe what you need is ASP.NET donunt caching. See here for a good explaination. I wouldn't be suprised if SO uses something like this for the top bar area.

Causeway answered 9/8, 2010 at 21:16 Comment(1)
Partial caching is available again in MVC 3! Woot!Causeway

© 2022 - 2024 — McMap. All rights reserved.