查看用户是否是C#+ Asp.net中Active Directory组的一部分

mik*_*e_h 46 c# asp.net active-directory active-directory-group .net-3.5

我需要一种方法来查看用户是否是我的.Net 3.5 asp.net c#应用程序中的活动目录组的一部分.

我正在使用msdn的标准ldap身份验证示例,但我真的没有看到如何检查组.

Nic*_*ver 38

使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用.NET 4.0,我不得不改变这一行,`var pc = new PrincipalContext(ContextType.Domain);```var pc = new PrincipalContext(ContextType.Domain,"MyDomainHere");`要摆脱例外.之后完美无缺. (11认同)

Dav*_*kle 19

Nick Craver的解决方案在.NET 4.0中对我不起作用.我收到有关卸载的AppDomain的错误.我没有使用它,而是使用了这个(我们只有一个域).这将检查组的组以及直接组成员身份.

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 + "\\", ""));
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 16

以下代码适用于.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();
}
Run Code Online (Sandbox Code Playgroud)


小智 10

最简单的解决方案

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);
Run Code Online (Sandbox Code Playgroud)


p.c*_*ell 7

如果您尝试确定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; }
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

这取决于用户是否在AD组中的含义.在AD中,组可以是安全组或通讯组.即使对于安全组,也取决于是否需要将"域用户"或"用户"等组包含在成员资格检查中.

IsUserInSecurityGroup将仅检查安全组,并且将适用于主要组类型的组,如"域用户"和"用户",而不是分发组.它还将解决嵌套组的问题.IsUserInAllGroup还将检查通讯组,但我不确定您是否会遇到权限问题.如果您这样做,请使用WAAG中的服务帐户(请参阅MSDN)

我没有使用UserPrincipal.GetAuthorizedGroups()的原因是因为它有很多问题,例如要求主叫帐户在WAAG中并且要求SidHistory中没有条目(参见David Thomas的评论)

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;
    }
Run Code Online (Sandbox Code Playgroud)