Вопрос по asp.net-mvc, active-directory, security, c#, .net – Проверка членства в группе Active Directory в .Net 4.5

7

У меня есть приложение ASP.Net MVC, использующее проверку подлинности Windows, и я проверяю членство в группах на предмет безопасности действий контроллера.

Как бы просто это ни звучало, я не нашел другого Вопроса, который мог бы решить проблему, с которой я столкнулся.

Первая попытка: [Авторизоваться]

Классический метод - просто ударитьAuthorize Атрибут аннотации данных на действие контроллера и перейти в город:

[Authorize(Roles = @"domain\groupName1")]

Нет кости. Мне предлагается ввести учетные данные. Обычно это означает, что что-то не так с конфигурацией аутентификации Windows, но все в порядке: (1)HttpContext.User этоWindowsPrincipal объект, и (2) я подтвердил еще одно известное название группы работ.

Вторая попытка: IsInRole ()

Следующим шагом было пойти по более старомодному маршруту и использоватьIPrincipal.IsInRole()и снова один возвращаетсяfalse, другойtrue.

var wp = (WindowsPrincipal)User;

// false
var inGroup1 = wp.IsInRole(@"domain\groupName1");
// true
var inGroup2 = wp.IsInRole(@"domain\groupName2");

Ошеломлен ... так что я ударил своих системных ботаников, и мы все перепроверили. Пользователь является членом группы? Да. Название группы написано правильно? Да. Следующим шагом было поймать SID.

Третья попытка: поиск групповой идентичности поиска

В моем контроллере я проверяюWindowsIdentity и просмотрите коллекцию группы для SID проблемной группы:

var wi = (WindowsIdentity)wp.Identity;
var group = wi.Groups.SingleOrDefault(g => g.Value == "group1-sidValue");

group переменнаяSecurityIdentifier объект. Поскольку он не равен нулю, мы можем быть уверены, что этот текущий пользователь является членом группы, которая[Authorize()] или жеIsInRole() попытки не подтверждают.

Четвертая попытка: DirectoryServices.AccountManagement

На этом этапе я схожу с ума и добавляю ссылку на 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.

Вопрос:

Что, черт возьми, я здесь пропустил? Почему обе методики проверки ролей потерпят неудачу, если в ходе исследования объекта станет ясно, что пользователь является действительным членом данной группы?

Тот факт, что одна группа проверяет нормально, а другая - не самая странная часть на данный момент.

Не ясно, работает ли Четвертая Попытка правильно. Также существует пятый способ получения сведений о пользователе: использовать запрос LDAP. Puterdo Borato
@PuterdoBorato - как 3-я, так и 4-я попытки доказывают, что рассматриваемый пользователь является частью рассматриваемой группы. группа, котораяIsInRole() а также[Authorize] терпят неудачу ... Я спрашиваю, почему он не может разрешить их в любом случае, если оставшиеся два способа четко подтверждают связь пользователя с группой one.beat.consumer
Не могли бы вы дать разрешение «LocalLogon» пользователю, который вы пытаетесь авторизовать, используя [Authorize] или IsInRole? Не могли бы вы рассказать о результате такой попытки? Благодарю. Puterdo Borato

Ваш Ответ

2   ответа
0

использующее проверку подлинности Windows, и я проверяю членство в группах на предмет безопасности действий контроллера. Как бы просто это ни звучало, я не нашел другого Вопроса, который мог бы решить проблему, с которой я столкнулся. Мне понадобилось много времени, чтобы найти что-тоhttp://www.c-sharpcorner.com/uploadfile/scottlysle/test-for-user-group-membership-in-Asp-Net-C-Sharp/

Мой код, чтобы проверить, принадлежит ли пользователь группе AD:

foreach (System.Security.Principal.IdentityReference group in System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups)
{
     if (String.Equals(group.Translate(typeof(System.Security.Principal.NTAccount)).ToString(), @"your_domain_name\your_group_name", StringComparison.InvariantCultureIgnoreCase))
     {
         // the user belongs to a group 
     }
}

Это все, что мне нужно, кроме<authentication mode="Windows"/> в файле Web.config

4
Ответ:

WindowsIdentity а такжеNTAccount (оба эти System.Security.Principal) и, наконец, фактическая запись Active Directory.

При проверкеWindowsIdentity против AD, если вы хотите использовать что-либо, кроме Сэма или Сид, вам нужно будет использоватьSystem.DirectoryServices.AccountManagement.

Предостережение. В .Net 4.5 участники безопасности включают в себя утверждения, но это не в контексте.

Длинное объяснение:

В веб-приложении с проверкой подлинности WindowsHttpContext.User этоWindowsPrincipal объект, оборачивающий базовыйWindowsIdentity.

WindowsIdentity в большинстве случаев имеет только два свойства, с которыми может быть идентифицирован аутентифицированный пользователь:Name а такжеUser.

Эти свойства переводятся в два свойства соответствующей записи учетной записи AD:

WindowsIdentity.Name = SamAccountName

WindowsIdentity.User = SID

[Authorize] атрибут фильтра в конечном итоге вызываетIsInRole(string role) на основной принцип ... иIsInRole() перегрузка строки создает экземплярNTAccount сrole («SamAccountName» в записи AD).

Это объясняет ошибку в # 1 и # 2 выше.

АвторизоватьHttpContext.User против чего-либо, кроме его / ее Sid или SamAccountName, вам понадобитсяDirectoryServices.AccountManagement или классический LDAP.

Похожие вопросы