Действительно медленный WindowsTokenRoleProvider
В приложении MVC5 я использую проверку подлинности Windows и хотел использовать наши группы Active Directory в качестве ролей, так как это строго приложение для внутренней сети. Я использую WindowsTokenRoleProvider так:
<roleManager defaultProvider="WindowsProvider" enabled="true" cacheRolesInCookie="false">
<providers>
<add name="WindowsProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
Я пробовал несколько других вариантов этой конфигурации, в том числе с использованием кеша cookie, но в конечном итоге это занимает ~20 секунд на проверку каждой группы. Я проверяю роль следующим образом:
User.IsInRole(@"Domain\UserName")
Я что-то упустил при настройке? Я не могу поверить, что для проверки подлинности было бы нормально занять 20 секунд. Пользователь, которого я проверяю, состоит из ~50 групп, но я не думал, что этого будет достаточно, чтобы сильно его замедлить.
1 ответ
Таким образом, лучшим решением на данный момент является вопрос стека
Я, вероятно, поиграю с тем, как роли проверяются / добавляются, чтобы увидеть, смогу ли я определить проблему, но я не ожидаю, что эта медлительность будет присутствовать только в 50 группах.
ОБНОВЛЕНИЕ: Так, фактически перечисляя мои группы, я обнаружил, что мой пользователь был в более чем 400 группах, что может объяснить, почему это заняло так много времени. Я до сих пор не понимаю, почему метод IsInRole для пользователя будет вызывать GetRolesForUser вместо того, чтобы просто вызывать IsUserInRole напрямую, но это делает экспоненциально быстрее
ОБНОВЛЕНИЕ 2: Старый ответ был удален, так вот мой класс:
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();
}
}