web-dev-qa-db-ja.com

ユーザーがC#+ Asp.netのActive Directoryグループの一部であるかどうかを確認します

ユーザーが.Net 3.5 asp.net c#アプリケーションのActive Directoryグループに属しているかどうかを確認する方法が必要です。

私はmsdnの標準のLDAP認証の例を使用していますが、実際にグループと照合する方法がわかりません。

46
mike_h

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;
}
38
Nick Craver

Nick Craverのソリューションは、.NET 4.0では機能しません。アンロードされたAppDomainに関するエラーが表示されます。それを使用する代わりに、これを使用しました(ドメインは1つしかありません)。これにより、グループのグループと直接のグループメンバーシップがチェックされます。

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 + "\\", ""));
    }
}
19
Dave Markle

以下のコードは.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();
}
16
Brandon Johnson

最も簡単なソリューション

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);
10
Adam

この方法は、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; }
    }
7
p.campbell

ユーザーが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;
    }
5
Terry Tsay

これははるかに簡単に思えます:

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
Randy Gamage

これが私の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);
    }
3
Leonidius
2
BC.

ブランドンジョンソン、それを気に入って、私はあなたが持っていたものを使いましたが、次の変更を行いました:

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();
}
1
Bill Daugherty

次のコードを試すことができます。

public bool Check_If_Member_Of_AD_Group(string username, string grouptoCheck, string domain, string ADlogin, string ADpassword)
{
    
     try {
        
        string EntryString = null;
        EntryString = "LDAP://" + domain;
        
        DirectoryEntry myDE = default(DirectoryEntry);
        
        grouptoCheck = grouptoCheck.ToLower();
        
        
        myDE = new DirectoryEntry(EntryString, ADlogin, ADpassword);
        
        DirectorySearcher myDirectorySearcher = new DirectorySearcher(myDE);
        
        myDirectorySearcher.Filter = "sAMAccountName=" + username;
        
        myDirectorySearcher.PropertiesToLoad.Add("MemberOf");
        
        SearchResult myresult = myDirectorySearcher.FindOne();
        
        int NumberOfGroups = 0;
        
        NumberOfGroups = myresult.Properties["memberOf"].Count - 1;
        
        string tempString = null;
        
        while ((NumberOfGroups >= 0)) {
            
            tempString = myresult.Properties["MemberOf"].Item[NumberOfGroups];
            tempString = tempString.Substring(0, tempString.IndexOf(",", 0));
            
            tempString = tempString.Replace("CN=", "");
            
            tempString = tempString.ToLower();
            tempString = tempString.Trim();
            
            if ((grouptoCheck == tempString)) {
                
                    
                return true;
            }
            
                
            NumberOfGroups = NumberOfGroups - 1;
        }
        
            
        return false;
    }
    catch (Exception ex) {
        
        System.Diagnostics.Debugger.Break();
    }
    //HttpContext.Current.Response.Write("Error: <br><br>" & ex.ToString)
}
1
Mick Walker

ユーザーの親グループに間接的にリンクされているネストされたグループを含むユーザーグループのメンバーシップを確認する場合は、次のように「tokenGroups」プロパティを使用してみてください。

 System.DirectoryServices 
 
の使用public static bool IsMemberOfGroupsToCheck(string DomainServer、string LoginID、string LoginPassword)
 {
 string UserDN = "CN = John.Doe-A、OU = Administration Accounts、OU = User Directory、DC = ABC、DC = com "
 string ADGroupsDNToCheck =" CN = ADGroupTocheck、OU = Administration Groups、OU = Group Directory、DC = ABC 、DC = com "; 
 
 byte [] sid、parentSID; 
 bool check = false; 
 DirectoryEntry parentEntry; 
 DirectoryEntry basechildEntry; 
 string octetSID; 
 
 basechildEntry = new DirectoryEntry( "LDAP://" + DomainServer + "/" + UserDN、LoginID、LoginPassword); 
 basechildEntry.RefreshCache (新しいString [] {"tokenGroups"}); 
 
 parentEntry = new DirectoryEntry( "LDAP://" + DomainServer + "/" + ADGroupsDNToCheck、LoginID、LoginPassword); 
 parentSID =(byte [])parentEntry.Properties ["objectSID"]。Value; 
 octetSID = ConvertToOctetString(parentSID、false、false); 
 
 foreach(basechildEntryのオブジェクトGroupSid .Properties ["tokenGroups"])
 {
 sid =(byte [])GroupSid; 
 if(ConvertToOctetString(sid、false、false)== octetSID)
 {
 check = true; 
 break; 
} 
} 
 
 basechildEntry.Dispose(); 
 parentEntry.Dispose(); 
 
 return check; 
} 
0
AsGoodAsLight
var context = new PrincipalContext(ContextType.Domain, {ADDomain}, {ADContainer});
var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, {AD_GROUP_NAME});
var user = UserPrincipal.FindByIdentity(context, {login});
bool result = user.IsMemberOf(group);
0