Does the Roles Manager cache data for a custom roles provider, and can I clear this cache?

1.5k views Asked by At

I'm using a custom role provider, which to over simplify gets a person object from the database using EF on .net 4 MVC project, and allocates user roles based on some rules around that (and other queries).

The data changes regularly, though changes are mode through code elsewhere in the system, not the roles provider. The roles provider is one way, and simply gets the roles a user is in.

When I change the database values, the role manager does not pick up on the change of roles until I do a recompile (by adding a space in web config for example), or the application otherwise restarts.

I've ensured the roles do not cache in a cookie by setting cacheRolesInCookie=false, which is what most help seems to point to, and presume there is a session cache built into the role manager.

I've modified the EF query which returns the person object to include a time stamp as part of the query. I can see through profiler the query is actually being called, and the time stamp changes each time, but my debug session shows stale data from the previous state for the 'person' item. There are other parts of the site that display data from the Person table, which show the up to date state.

I don't really understand how the debugger should behave on cached data. I don't see why the EF query would fire at all if it's a cache issue, but the person data is definitely showing state as per the first run, not as per the current state of the table row.

I feel I'm missing something obvious. Does the Role Manager cache data in session?

2

There are 2 answers

1
jkriddle On BEST ANSWER

The answer really depends on the architecture of your application. I had this problem recently and was blaming the Role Manager cache as well. Turns out it was the management of the Entity context in my Data Access Layer altogether. I was managing my Entity Context and storing the context per-request as is typically recommended. However the problem was that the context was being set twice due to an unrelated defect, and so the Role Provider's context was always different than the rest of the application, and was only set once (since the Role Provider is instantiated on Application Start, not per-request).

I'd recommend looking how you are storing data contexts and trace through to see how that is being stored in relation to your Role Manager vs the rest of the application. Ensure you are truly only using one context per request.

0
davrob01 On

I have an answer for "Can I clear this cache?"

Yes, you can clear the Role Manager cache.

(note: this method is different from deleting the role cache cookie and allows you to clear the cache during a request).

The Role Manager will cache roles for the current user in HttpContext.Current.User after the first call to the role provider to get the roles.

That cache will be used in subsequent role checks throughout the request, and your custom role provider will not be called.

However, you can force the Role Manager to call your role provider again (and effectively re-grab the roles from the data source) by casting the current user to a RolePrincipal and then calling SetDirty()

For example:

RolePrincipal currentUser = HttpContext.Current.User as RolePrincipal;
currentUser.SetDirty();

See MS Documentation on RolePrincipal.SetDirty Method