Проверка членства в группе Active Directory в .Net 4.5
У меня есть приложение ASP.Net MVC, использующее проверку подлинности Windows, и я проверяю членство в группах на предмет безопасности действий контроллера.
Просто, как это звучит, яЯ не нашел другого Вопроса, который мог бы решить проблему, с которой я столкнулся.
Первая попытка: [Авторизоваться]Классический метод - просто ударитьAuthorize
Атрибут аннотации данных на действие контроллера и перейти в город:
[Authorize(Roles = @"domain\groupName1")]
Нет кости. Мне предлагается ввести учетные данные. Обычно это означает, что что-то не так с конфигурацией аутентификации Windows, но этоХорошая настройка: (1)HttpContext.User
этоWindowsPrincipal
объект, и (2) я подтвердил еще одно известное название группы работ.
Следующим шагом было пойти по более старомодному маршруту и использоватьIPrincipal.IsInRole()
и снова возвращаетсяfalse
, другой .true
var wp = (WindowsPrincipal)User;
// false
var inGroup1 = wp.IsInRole(@"domain\groupName1");
// true
var inGroup2 = wp.IsInRole(@"domain\groupName2");
Ошеломлен ... так что я ударил своих системных ботаников, и мы все перепроверили. Пользователь является членом группы? Да. Название группы написано правильно? Да. Следующим шагом было поймать SID.
Третья попытка: поиск личностиКоллекция группы sВ моем контроллере я проверяюWindowsIdentity
и просмотрите коллекцию группы для SID проблемной группы:
var wi = (WindowsIdentity)wp.Identity;
var group = wi.Groups.SingleOrDefault(g => g.Value == "group1-sidValue");
group
переменнаяSecurityIdentifier
объект. Поскольку он не равен нулю, мы можем быть уверены, что этот текущий пользователь является членом группы, которая[Authorize()]
или жеIsInRole()
попытки не подтверждают.
На данный момент яЯ схожу с ума и добавлю ссылку на API AccountManagement. Я ищу контекст домена дляGroupPrincipal
по имени и SID:
var pc = new PrincipalContext(ContextType.Domain, "domain");
var gp1byName = GroupPrincipal.FindByIdentity(pc, "groupName1")
var gp1bySid = GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, "group1-sidValue");
Обе основные переменные группы созрели с одним и тем же объектом, и я проверил через переменную наблюдения, что принципалMembers
Коллекция содержитUserPrincipal
объект с тем же SID, что и текущийWindowsPrincipal
на.HttpContext
Что, черт возьми, я здесь пропустил? Почему обе методики проверки ролей потерпят неудачу, если в ходе исследования объекта станет ясно, что пользователь является действительным членом данной группы?
Тот факт, что одна группа проверяет нормально, а другая - не самая странная часть на данный момент.