Смотрите, если пользователь является частью группы Active Directory в C # + Asp.net - PullRequest
46 голосов
/ 03 февраля 2010

Мне нужен способ узнать, входит ли пользователь в группу активных каталогов из моего приложения .Net 3.5 asp.net c #.

Я использую стандартный пример аутентификации ldap из msdn, но я не вижу, как проверить группу.

Ответы [ 13 ]

38 голосов
/ 03 февраля 2010

С 3.5 и System.DirectoryServices.AccountManagement это немного чище:

public List<string> GetGroupNames(string userName)
{
  var pc = new PrincipalContext(ContextType.Domain);
  var src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc);
  var result = new List<string>();
  src.ToList().ForEach(sr => result.Add(sr.SamAccountName));
  return result;
}
19 голосов
/ 14 июня 2010

Решение Ника Крейвера не работает для меня в .NET 4.0. Я получаю сообщение об ошибке в незагруженном домене приложений. Вместо этого я использовал это (у нас только один домен). Это будет проверять группы групп, а также прямое членство в группах.

using System.DirectoryServices.AccountManagement;
using System.Linq;

...

using (var ctx = new PrincipalContext(ContextType.Domain, yourDomain)) {
    using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, yourGroup)) {
        bool isInRole = grp != null && 
            grp
            .GetMembers(true)
            .Any(m => m.SamAccountName == me.Identity.Name.Replace(yourDomain + "\\", ""));
    }
}
16 голосов
/ 08 декабря 2011

Код ниже будет работать в .net 4.0

private static string[] GetGroupNames(string userName)
{
    List<string> result = new List<string>();

    using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"))
    {
        using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc))
        {
            src.ToList().ForEach(sr => result.Add(sr.SamAccountName));
        }
    }

    return result.ToArray();
}
10 голосов
/ 21 марта 2013

простейшее решение

PrincipalContext pc = new PrincipalContext((Environment.UserDomainName == Environment.MachineName ? ContextType.Machine : ContextType.Domain), Environment.UserDomainName);

GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "{GroupName}");
UserPrincipal up = UserPrincipal.FindByIdentity(pc, Environment.UserName);
up.IsMemberOf(gp);
7 голосов
/ 06 сентября 2013

Этот метод может быть полезен, если вы пытаетесь определить, принадлежит ли текущий пользователь, прошедший проверку подлинности Windows, определенной роли.

public static bool CurrentUserIsInRole(string role)
{
    try
    {
        return System.Web.HttpContext.Current.Request
                    .LogonUserIdentity
                    .Groups
                    .Any(x => x.Translate(typeof(NTAccount)).ToString() == role);
        }
        catch (Exception) { return false; }
    }
5 голосов
/ 31 января 2013

Это зависит от того, что вы имеете в виду, если пользователь находится в группе AD.В AD группы могут быть группой безопасности или группой рассылки.Даже для групп безопасности это зависит от того, нужно ли включать в проверку членства такие группы, как «Пользователи домена» или «Пользователи».

IsUserInSecurityGroup будет проверять только группы безопасности и будет работать для групп основных типов.как «Пользователи домена» и «Пользователи», а не группы рассылки.Это также решит проблему с вложенными группами.IsUserInAllGroup также проверит наличие групп рассылки, но я не уверен, что у вас возникнут проблемы с разрешениями.Если вы это сделаете, используйте учетную запись службы, которая находится в WAAG ( См. MSDN )

Причина, по которой я не использую UserPrincipal.GetAuthorizedGroups (), заключается в том, что у нее много проблем, таких кактребование, чтобы вызывающая учетная запись была в WAAG, и отсутствие записи в SidHistory ( См. комментарий Дэвида Томаса )

public bool IsUserInSecurityGroup(string user, string group)
    {
        return IsUserInGroup(user, group, "tokenGroups");
    }
    public bool IsUserInAllGroup(string user, string group)
    {
        return IsUserInGroup(user, group, "tokenGroupsGlobalAndUniversal");
    }

    private bool IsUserInGroup(string user, string group, string groupType)
    {
        var userGroups = GetUserGroupIds(user, groupType);
        var groupTokens = ParseDomainQualifiedName(group, "group");
        using (var groupContext = new PrincipalContext(ContextType.Domain, groupTokens[0]))
        {
            using (var identity = GroupPrincipal.FindByIdentity(groupContext, IdentityType.SamAccountName, groupTokens[1]))
            {
                if (identity == null)
                    return false;

                return userGroups.Contains(identity.Sid);
            }
        }
    }
    private List<SecurityIdentifier> GetUserGroupIds(string user, string groupType)
    {
        var userTokens = ParseDomainQualifiedName(user, "user");
        using (var userContext = new PrincipalContext(ContextType.Domain, userTokens[0]))
        {
            using (var identity = UserPrincipal.FindByIdentity(userContext, IdentityType.SamAccountName, userTokens[1]))
            {
                if (identity == null)
                    return new List<SecurityIdentifier>();

                var userEntry = identity.GetUnderlyingObject() as DirectoryEntry;
                userEntry.RefreshCache(new[] { groupType });
                return (from byte[] sid in userEntry.Properties[groupType]
                        select new SecurityIdentifier(sid, 0)).ToList();
            }
        }
    }
    private static string[] ParseDomainQualifiedName(string name, string parameterName)
    {
        var groupTokens = name.Split(new[] {"\\"}, StringSplitOptions.RemoveEmptyEntries);
        if (groupTokens.Length < 2)
            throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName);
        return groupTokens;
    }
3 голосов
/ 08 апреля 2015

Это кажется намного проще:

public bool IsInRole(string groupname)
{
    var myIdentity = WindowsIdentity.GetCurrent();
    if (myIdentity == null) return false;

    var myPrincipal = new WindowsPrincipal(myIdentity);
    var result = myPrincipal.IsInRole(groupname);

    return result;
}
3 голосов
/ 30 марта 2015

Вот мои 2 цента.

    static void CheckUserGroup(string userName, string userGroup)
    {
        var wi = new WindowsIdentity(userName);
        var wp = new WindowsPrincipal(wi);

        bool inRole = wp.IsInRole(userGroup);

        Console.WriteLine("User {0} {1} member of {2} AD group", userName, inRole ? "is" : "is not", userGroup);
    }
2 голосов
/ 03 февраля 2010
1 голос
/ 07 августа 2012

Брэндон Джонсон, мне понравилось, я использовал то, что у тебя было, но сделал следующее изменение:

private static string[] GetGroupNames(string domainName, string userName)
{
    List<string> result = new List<string>();

    using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domainName))
    {
        using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(principalContext, userName).GetGroups(principalContext))
        {
            src.ToList().ForEach(sr => result.Add(sr.SamAccountName));
        }
    }

    return result.ToArray();
}
...