ASP .NET Custom RoleProvider не уважает cacheRolesInCookie = "true" - PullRequest
6 голосов
/ 19 июля 2010

Я реализовал пользовательский поставщик ролей и настроил его в своем файле web.config следующим образом:

<roleManager enabled="true" defaultProvider="TDRoleProvider" cacheRolesInCookie="true">
  <providers>
    <clear/>
    <add name="TDRoleProvider" type="TDRoleProvider"/>
  </providers>
</roleManager>

Я переопределил функцию GetRolesForUser в своем поставщике пользовательских ролей, и я вошел в нее, и она работает просто отлично - загружает 60 ролей для пользователя, с которым я тестирую. Однако я заметил, что GetRolesForUser вызывается при каждом запросе, который вызывает User.IsInRole. В других приложениях, которые я написал, он вызывает его только один раз, а затем кэширует результат в файле cookie. По какой-то причине кеширование не работает для этого приложения. Есть идеи, почему?

Ответы [ 3 ]

3 голосов
/ 25 мая 2013

У меня была такая же проблема. В моем случае проблема заключалась в том, что я устанавливал 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 проверяет наличие пустых и пустых значений:

    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);
        }

Сохранить роль Cookie

    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 и зарегистрируйте его глобально. См. здесь .

2 голосов
/ 11 сентября 2010

http://connect.microsoft.com/VisualStudio/feedback/details/104688/rolemanager-cacherolesincookie-option-does-not-work

"Вопрос о том, когда кэшировать (или не кэшировать) в RolePrincipal, прошел через несколько итераций проектирования, и мы, наконец, остановились только на кэшировании для метода, предоставляемого интерфейсом IPrincipal (т.е. IsInRole)."

1 голос
/ 22 августа 2010

То же самое для меня.Он продолжает вызывать GetRolesForUser ()

...