У меня есть приложение ASP.NET 3.5, использующее аутентификацию Windows и реализующее наш собственный RoleProvider.
Проблема в том, что мы хотим ограничить доступ к набору страниц несколькими тысячами пользователей, и вместо того, чтобы вводить все по одному, мы обнаружили, что они принадлежат группе AD.
Ответ прост, если общая группа, в которой мы проверяем членство конкретного пользователя, является его непосредственным членом, но проблема в том, что если группа является членом другой группы, а затем впоследствии членом другой группы тогда мой код всегда возвращает ложь.
Например: скажем, мы хотим проверить, является ли Пользователь членом группы E , но Пользователь не является прямым членом * E ", она является членом "A", который является членом "B", который действительно является членом E , поэтому Пользователь является членом * E "
Одно из решений, которое у нас есть, очень медленное, хотя и дает правильный ответ
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, "DL-COOL-USERS"))
{
var users = group.GetMembers(true); // recursively enumerate
return users.Any(a => a.Name == "userName");
}
}
Исходное решение и то, что я пытался заставить работать, используя .NET 3.5 System.DirectoryServices.AccountManagement и оно работает, когда пользователи являются прямыми членами рассматриваемой группы, выглядит следующим образом:
public bool IsUserInGroup(string userName, string groupName)
{
var cxt = new PrincipalContext(ContextType.Domain, "DOMAIN");
var user = UserPrincipal.FindByIdentity(cxt, IdentityType.SamAccountName, userName);
if (user == null)
{
return false;
}
var group = GroupPrincipal.FindByIdentity(cxt, groupName);
if (group == null)
{
return false;
}
return user.IsMemberOf(group);
}
Суть в том, что нам нужно проверять членство, даже если группы вложены на многих уровнях вниз.
Большое спасибо!