Question

In an MVC5 application I am using Windows Authentication and wanted to use our Active Directory Groups as roles as this is strictly and intranet application. I am using the WindowsTokenRoleProvider as so:

<roleManager defaultProvider="WindowsProvider" enabled="true" cacheRolesInCookie="false">
  <providers>
    <add name="WindowsProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
  </providers>
</roleManager>

I have tried a few other variations of that config including using the cookie cache, but the end result is that it takes ~20 seconds per group check. I check role like this:

User.IsInRole(@"Domain\UserName")

Is there something I have completely missed in setting this up? I can't believe it would be normal for authentication to take 20 seconds per check. The user I am checking is in ~50 groups, but I didn't think that would be enough to slow it down so much.

Was it helpful?

Solution

So best solution at this point seems to be this stackoverflow question

I will probably play around with how the roles get checked/added to see if I can pinpoint the issue, but I wouldn't expect this slowness from only being in 50 groups.

UPDATE: So while actually enumerating my groups I found my user was in over 400 groups which might explain why it took so long. I still don't under stand why the IsInRole method on user would call GetRolesForUser instead of just calling IsUserInRole directly, but this makes things exponentially faster

UPDATE 2: Old answer was deleted so here is my class:


    public class CustomWindowsTokenRoleProvider : WindowsTokenRoleProvider
    {
        public override string[] GetRolesForUser(string username)
        {
            List roles = null;
            string key = String.Concat(username, ":", base.ApplicationName);
            Cache cache = HttpContext.Current.Cache;

            if (cache[key] != null)
            {
                roles = new List(cache[key] as string[]);
            }

            if (roles == null)
            {
                roles = new List();

                // AppSettings.APPLICATION_GROUPS is an IEnumerable that returns just the groups that my application is interested in checking against
                foreach (string role in AppSettings.APPLICATION_GROUPS)
                {
                    if (base.IsUserInRole(username, role));
                    {
                        roles.Add(role);
                    }
                }

                cache.Insert(key, roles.ToArray(), null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
            }

            return roles.ToArray();
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top