ASP .NET自定义RoleProvider未遵守cacheRolesInCookie="true"属性

7
我已经实现了一个自定义的角色提供程序,并在web.config文件中进行了配置,如下所示:
<roleManager enabled="true" defaultProvider="TDRoleProvider" cacheRolesInCookie="true">
  <providers>
    <clear/>
    <add name="TDRoleProvider" type="TDRoleProvider"/>
  </providers>
</roleManager>

我已经重写了自定义角色提供程序中的GetRolesForUser函数,并且我已经进入它,它可以正常工作-为我测试的用户加载了60个角色。然而,我注意到每个调用User.IsInRole的请求都会调用GetRolesForUser。在我编写的其他应用程序中,它只调用一次,然后将结果缓存到cookie中。由于某种原因,此应用程序的缓存不起作用。有什么想法吗?

3个回答

3
我是同样遇到了这个问题。在我的情况下,问题是我将 Context.User 设置为 GenericPrincipal 而不是 RolePrincipal。所以应该改成:
this.Context.User = new GenericPrincipal(customIdentity, roles);

这对我有用:
            HttpCookie roleCookie = this.Context.Request.Cookies[Roles.CookieName];
            if (IsValidAuthCookie(roleCookie))
            {
                this.Context.User = new RolePrincipal(customIdentity, roleCookie.Value);
            }
            else
            {
                this.Context.User = new RolePrincipal(customIdentity);
                var x = this.Context.User.IsInRole("Visitor"); // do this to cache the results in the cookie
            }

IsValidAuthCookie 方法检查是否为 null 或空:

    private static bool IsValidAuthCookie(HttpCookie authCookie)
    {
        return authCookie != null && !String.IsNullOrEmpty(authCookie.Value);
    }

更新:升级到MVC5 .NET 4.5后,roleManager停止工作(不保存cookie中的角色),因此我不得不自己保存它:

        HttpCookie roleCookie = filterContext.HttpContext.Request.Cookies[Roles.CookieName];
        if (IsValidAuthCookie(roleCookie))
        {
            filterContext.Principal = new RolePrincipal(customIdentity, roleCookie.Value);
            RolePrincipal rp = (RolePrincipal)filterContext.Principal;
            if (!rp.IsRoleListCached) // check if roles loaded properly (if loads old cookie from another user for example, roles won't be loaded/cached).
            {
                // roles not loaded. Delete and save new
                Roles.DeleteCookie();
                rp.IsInRole("Visitor"); // load Roles
                SaveRoleCookie(rp, filterContext);
            }

        }
        else
        {
            filterContext.Principal = new RolePrincipal(customIdentity);
            filterContext.Principal.IsInRole("Visitor"); // do this to cache the results in the cookie.
            SaveRoleCookie(filterContext.Principal as RolePrincipal, filterContext);
        }

保存 roleCookie

    private void SaveRoleCookie(RolePrincipal rp, AuthenticationContext filterContext)
    {
        string s = rp.ToEncryptedTicket();
        const int MAX_COOKIE_LENGTH = 4096;
        if (string.IsNullOrEmpty(s) || s.Length > MAX_COOKIE_LENGTH)
        {
            Roles.DeleteCookie();
        }
        else
        {
            HttpCookie cookie = new HttpCookie(Roles.CookieName, s);
            cookie.HttpOnly = true;
            cookie.Path = Roles.CookiePath;
            cookie.Domain = Roles.Domain;
            if (Roles.CreatePersistentCookie)
                cookie.Expires = rp.ExpireDate;
            cookie.Secure = Roles.CookieRequireSSL;
            filterContext.HttpContext.Response.Cookies.Add(cookie);
        }
    }

将此代码放在AuthenticationFilter上并全局注册。请参见这里

我已经花了几个小时在这个问题上搜索,这个解决方法很有效!非常感谢您发布这个!您能回答一个问题吗?方法IsValidAuthCookie的引用是什么或者实现该方法的代码所在的类是什么? - Ben Gripka
谢谢,这个答案帮了我很多。这是唯一一个解决方案,可以解决在实现自己的RoleProvider时,在MVC 5中缓存不再工作的问题。我把它放在了我的授权属性中。 - Lee

3

那么有什么更好的方法来实现这个?我希望将角色缓存在cookie中。 - Brandon Montgomery
试错和仔细选择要使用的方法,我想。 - Greg

1

对我来说也是一样的。它一直在调用GetRolesForUser()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接