We have an ASP.NET MVC application for which we have developed our own custom RoleProvider class. Without caching it will access the datastore for every request - bad. The only caching option we can find is (in web.config) via cookies stored on the clients' machines. My two questions are:
Does anyone have an alternative route? I understand that caching this information in the Session is also bad?
Any (Default)- Content is cached in three locations- the Web Server, any proxy Servers and the Web Browser. Client- Content is cached on the Web Browser. Server- Content is cached on the Web Server. ServerAndClient- Content is cached on the Web Server and the Web Browser.
Two common approaches are cache-aside or lazy loading (a reactive approach) and write-through (a proactive approach). A cache-aside cache is updated after the data is requested. A write-through cache is updated immediately when the primary database is updated.
In this, you learn how to cache the output returned from a controller action so that a new user doesn't need to create the same content every time the action is called. Using the OutputCache attribute, you can enable output caching functionality by applying an individual controller action or an entire controller class.
If you have developed your own custom RoleProvider class, you can do your own data caching, e.g. using the ASP.NET cache. This is more flexible than using Session as a cache, since it will work even on pages that don't have session state enabled.
I don't agree with Wyatt Barnett's comment that:
The downside for using the Session ... the fact that Session storage is very violate and not particularly reliable
It's OK for a cache (whether Session, the ASP.NET Cache or something else) to be volatile - you just need to repopulate it when required.
To answer your questions:
It's as secure as the encryption used to encrypt the cookie. If you're relying on FormsAuthentication, it need be no less secure than the Forms Authentication ticket.
The cookie will be transmitted with every request. So there is a potential performance hit if users can have a very large number of roles, and the potential to exceed the maximum cookie size supported by the browser.
While the idea that querying the DB each request is inefficient is true, but remember that SELECT performance on properly indexed tables in modern DBs is blazingly fast, so I would first take some measurements to be sure that this scenario actually negatively effects performance versus theoretically could negatively effect performance at a later date.
The downside for using the Session isn't so much the overhead (minimal) as the fact that Session storage is very violate and not particularly reliable. You can easily lose the session and still have a logged in user, for example.
That said, a good way to settle in the middle here would be to cache the user's roles per request using the HttpContext.Items collection. This will limit to one SELECT per request, which is probably reasonably efficient (cf measurement above) while avoiding the other storage issues--such as a fat, insecure cookie or some rather violate Session-based solution.
The cookie information will in fact be sent from the browser to your web server with every request, that's just how cookies work, but as long as the size of the cookie is reasonable it shouldn't have too much of an impact on performance. If you are using forms authentication I would recommend storing the roles in the forms authentication cookie as described in this blog post. In that case, you are just adding data to a cookie that already exists. You should be aware that there is an upper limit to the amount of data you can store in that cookie however, as described here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With