1

This used to work, however I recently discovered that ASP.NET is not caching user roles in the cookie anymore. I ran a fiddler trace and it appears that the value for the cookie is blank and the expiration date is set in the past. Therefore the cookie is not sent on the subsequent request and the DB is hit every round trip.

I can't seem to find any posts on this. Any help would be great. Thanks!

web.config:

<roleManager enabled="true" defaultProvider="MyRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" createPersistentCookie="false">
  <providers>
    <clear />
    <add name="MyRoleProvider" type="MyCompany.Core.Web.Providers.MyRoleProvider" connectionStringName="MainConnect" applicationName="MyApplication" />
  </providers>
</roleManager>

Fiddler Response (Header):

HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXROLES=; expires=Tue, 12-Oct-1999 05:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Mon, 31 Dec 2012 01:14:19 GMT
Content-Length: 1381
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Bill Christenson
  • 799
  • 1
  • 9
  • 20

3 Answers3

1

Take a look at This answer. It seems to indicate that only the IsUserInRole member of the provider will cache results this way. When checking user roles, ASP .NET MVC seems to use GetRolesForUser exclusively. I bumped into this same limitation not too long ago--here's some code I added to my role provider to provide a simple caching mechanism.

 public class MyRoleProvider : RoleProvider
 {
    private readonly string userRoleCacheKeyFormat;

    public MyRoleProvider()
    {
        userRoleCacheKeyFormat = this.Name + "_{0}";
    }

    public override string[] GetRolesForUser(string username)
    {
        return GetUserRoles(username);
    }

    private string[] GetUserRoles(string username)
    {
        string[] roleNames = null;

        if (!TryGetCachedUserRoles(username, out roleNames))
        {
            //cache miss
            roleNames = GetUserRolesFromStore(username);
        }

        return roleNames;
    }

    private bool TryGetCachedUserRoles(string username, out string[] userRoles)
    {
        string cacheKey = string.Format(userRoleCacheKeyFormat, username);
        HttpContext httpContext = HttpContext.Current;
        if (httpContext != null)
        {
            userRoles = (string[])httpContext.Cache.Get(cacheKey);
        }
        else { userRoles = null; }

        return (userRoles != null);
    }

    private void CacheUserRoles(string username, string[] userRoles)
    {
        string cacheKey = string.Format(userRoleCacheKeyFormat, username);
        HttpContext httpContext = HttpContext.Current;
        if (httpContext != null)
        {
            httpContext.Cache.Insert(cacheKey, userRoles, null, DateTime.UtcNow.AddMinutes(15), Cache.NoSlidingExpiration);
        }
    }

    private string[] GetUserRolesFromStore(string username)
    {
        MyDbContext db = MvcApplication.IoC.Resolve<MyDbContext>();

        string[] roleNames = db.Users
            .Single(u => u.Username == username)
            .UserRoles
            .Select(r => r.Name)
            .ToArray();

        CacheUserRoles(username, roleNames);

        return roleNames;
    }
}
Community
  • 1
  • 1
grin0048
  • 534
  • 5
  • 13
0

I think. That Session doesn't have any Role.

halit
  • 1,128
  • 1
  • 11
  • 27
  • The user has roles assigned. I can set the breakpoint in the RolesProvider and see the array of roles returned. This has nothing to do with Session as cookies are being used to cache the roles... not the Session. – Bill Christenson Jan 03 '13 at 18:51
0

try createPersistentCookie="true"

Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
sol
  • 1