Если вы используете .NET 3.5 или System.DirectoryServices.AccountManagement
новее , вы можете использовать новое пространство имен (S.DS.AM), которое делает это намного проще, чем раньше.
Прочтите об этом здесь: Управление принципами безопасности каталогов в .NET Framework 3.5
Обновление: старые статьи журнала MSDN, к сожалению, больше не доступны в Интернете - вам нужно загрузить CHM для журнала MSDN за январь 2008 года от Microsoft и прочитать там статью.
По сути, вам нужно иметь «основной контекст» (обычно ваш домен), участника-пользователя, и тогда вы очень легко получите его группы:
public List<GroupPrincipal> GetGroups(string userName)
{
List<GroupPrincipal> result = new List<GroupPrincipal>();
// establish domain context
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find your user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
// if found - grab its groups
if(user != null)
{
PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
// iterate over all groups
foreach(Principal p in groups)
{
// make sure to add only group principals
if(p is GroupPrincipal)
{
result.Add((GroupPrincipal)p);
}
}
}
return result;
}
и это все! Теперь у вас есть результат (список) групп авторизации, к которым принадлежит пользователь - переберите их, распечатайте их имена или все, что вам нужно сделать.
Обновление: чтобы получить доступ к определенным свойствам, которые не отображаются на UserPrincipal
объекте, вам нужно покопаться в нижележащих DirectoryEntry
:
public string GetDepartment(Principal principal)
{
string result = string.Empty;
DirectoryEntry de = (principal.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
if (de.Properties.Contains("department"))
{
result = de.Properties["department"][0].ToString();
}
}
return result;
}
Обновление №2: кажется, не должно быть слишком сложно соединить эти два фрагмента кода вместе .... но хорошо - вот оно:
public string GetDepartment(string username)
{
string result = string.Empty;
// if you do repeated domain access, you might want to do this *once* outside this method,
// and pass it in as a second parameter!
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find the user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, username);
// if user is found
if(user != null)
{
// get DirectoryEntry underlying it
DirectoryEntry de = (user.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
if (de.Properties.Contains("department"))
{
result = de.Properties["department"][0].ToString();
}
}
}
return result;
}
UserPrincipal
- см. Мой обновленный ответ, чтобы узнать, как его получить.GetAuthorizationGroups()
не находит вложенных групп. Чтобы действительно получить все группы, членом которых является данный пользователь (включая вложенные группы), попробуйте следующее:Я использую,
try/catch
потому что у меня были некоторые исключения с 2 из 200 групп в очень большом AD, потому что некоторые SID были больше недоступны. (Translate()
Вызов выполняет преобразование SID -> Name.)источник
Прежде всего, GetAuthorizationGroups () - отличная функция, но, к сожалению, имеет 2 недостатка:
Поэтому я написал небольшую функцию для замены GetAuthorizationGroups () более производительной и безопасной. Он выполняет только 1 вызов LDAP с запросом с использованием индексированных полей. Его можно легко расширить, если вам нужно больше свойств, чем только имена групп (свойство "cn").
источник
В AD у каждого пользователя есть собственность
memberOf
. Он содержит список всех групп, к которым он принадлежит.Вот небольшой пример кода:
источник
В моем случае единственным способом, которым я мог продолжать использовать GetGroups () без каких-либо ограничений, было добавление пользователя (USER_WITH_PERMISSION) в группу, у которой есть разрешение на чтение AD (Active Directory). Чрезвычайно важно создать PrincipalContext, передающий этого пользователя и пароль.
Действия, которые вы можете выполнить в Active Directory, чтобы заставить его работать:
источник
Это работает для меня
источник
Ответ зависит от того, какие группы вы хотите получить. Пространство
System.DirectoryServices.AccountManagement
имен предоставляет два метода группового поиска:Так
GetGroups
становится все группы , в которые пользователь является прямым участником, иGetAuthorizationGroups
получает все авторизации группы из которых пользователь является прямым или косвенным членом.Несмотря на то, как они названы, одно не является подмножеством другого. Могут быть группы, возвращенные
GetGroups
не возвращенным пользователемGetAuthorizationGroups
, и наоборот.Вот пример использования:
источник
Мое решение:
источник
Если Translate работает локально, но не удаленно, группа ei. Перевести (typeof (NTAccount)
Если вы хотите, чтобы код приложения выполнялся с использованием идентификатора LOGGED IN USER, включите олицетворение. Олицетворение можно включить через IIS или добавив следующий элемент в файл web.config .
Если олицетворение включено, приложение выполняется с разрешениями, указанными в вашей учетной записи. Таким образом, если зарегистрированный пользователь имеет доступ к определенному сетевому ресурсу, только тогда он сможет получить доступ к этому ресурсу через приложение.
Благодарим PRAGIM tech за эту информацию из его прилежного видео.
Аутентификация Windows в asp.net, часть 87:
https://www.youtube.com/watch?v=zftmaZ3ySMc
Но выдача себя за другое лицо создает много накладных расходов на сервере.
Лучшее решение, позволяющее пользователям определенных сетевых групп - запретить анонимность в веб-конфигурации.
<authorization><deny users="?"/><authentication mode="Windows"/>
и в вашем коде позади, предпочтительно в global.asax, используйте HttpContext.Current.User.IsInRole :
ПРИМЕЧАНИЕ: Группа должна быть написана с обратной косой чертой \ т.е. "TheDomain \ TheGroup"
источник