Determining members of local groups via C#

2019-03-16 21:28发布

I wondered whether anybody knows how to obtain membership of local groups on a remote server programmatically via C#. Would this require administrator permissions? And if so is there any way to confirm the currently logged in user's membership (or not) of these groups?

6条回答
聊天终结者
2楼-- · 2019-03-16 21:55

Howto: (Almost) Everything In Active Directory via C# is very helpfull and also includes instructions on how to iterate AD members in a group.

public ArrayList Groups(string userDn, bool recursive)
{
    ArrayList groupMemberships = new ArrayList();
    return AttributeValuesMultiString("memberOf", userDn,
        groupMemberships, recursive);
}

You will also need this function:

public ArrayList AttributeValuesMultiString(string attributeName,
     string objectDn, ArrayList valuesCollection, bool recursive)
{
    DirectoryEntry ent = new DirectoryEntry(objectDn);
    PropertyValueCollection ValueCollection = ent.Properties[attributeName];
    IEnumerator en = ValueCollection.GetEnumerator();

    while (en.MoveNext())
    {
        if (en.Current != null)
        {
            if (!valuesCollection.Contains(en.Current.ToString()))
            {
                valuesCollection.Add(en.Current.ToString());
                if (recursive)
                {
                    AttributeValuesMultiString(attributeName, "LDAP://" +
                    en.Current.ToString(), valuesCollection, true);
                }
            }
        }
    }
    ent.Close();
    ent.Dispose();
    return valuesCollection;
}

If you do now want to use this AD-method, you could use the info in this article, but it uses unmanaged code:

http://www.codeproject.com/KB/cs/groupandmembers.aspx

The sample application that they made:

alt text

查看更多
神经病院院长
3楼-- · 2019-03-16 21:58

It appears there is a new Assembly in .net 3.5 called System.DirectoryServices.AccountManagement which gives a cleaner implementation than System.DirectoryServices. Dominick Baier blogs about a couple of simple operations including checking membership of a group:-

public static bool IsUserInGroup(string username, string groupname, ContextType type)
{
    PrincipalContext context = new PrincipalContext(type);

    UserPrincipal user = UserPrincipal.FindByIdentity(
        context,
        IdentityType.SamAccountName,
        username);
    GroupPrincipal group = GroupPrincipal.FindByIdentity(
        context, groupname);

    return user.IsMemberOf(group);
}

I think I will use this approach, thanks for the suggestions though however! :-)

查看更多
不美不萌又怎样
4楼-- · 2019-03-16 22:03

I asked a similar question, and ended up writing an answer which used WMI to enum the group members. I had real problems with authentication in the system.directoryservices.accountmanagement stuff. YMMV, of course.

查看更多
相关推荐>>
5楼-- · 2019-03-16 22:06

I'd be curious if the System.DirectoryServices.AccountManagement is fully managed. I've used System.DirectoryServices.ActiveDirectory which is a wrapper for COM Interop which has led to many headaches...

查看更多
\"骚年 ilove
6楼-- · 2019-03-16 22:10

Perhaps this is something that can be done via WMI?

查看更多
闹够了就滚
7楼-- · 2019-03-16 22:17

This may possibly help. I had to develop an app where we want to authenticate against active directory, and also examine the groups strings that the user is in.

For a couple of reasons we don't want to use windows authentication, but rather have our own forms based authentication. I developed the routine below to firstly authenticate the user, and secondly examine all the groups that the user belongs to. Perhaps it may help. The routine uses LogonUser to authenticate, and then gets the list of numerical guid-like group ids (SIDs) for that user, and translates each one to a human readable form.

Hope this helps, I had to synthesise this approach from a variety of different google searches.

private int validateUserActiveDirectory()
{
    IntPtr token = IntPtr.Zero;
    int DBgroupLevel = 0;

    // make sure you're yourself -- recommended at msdn http://support.microsoft.com/kb/248187
    RevertToSelf();

    if (LogonUser(txtUserName.Value, propDomain, txtUserPass.Text, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) != 0) {
        // ImpersonateLoggedOnUser not required for us -- we are not doing impersonated stuff, but leave it here for completeness.
        //ImpersonateLoggedOnUser(token);
        // do impersonated stuff
        // end impersonated stuff

        // ensure that we are the original user
        CloseHandle(token);
        RevertToSelf();

        System.Security.Principal.IdentityReferenceCollection groups = Context.Request.LogonUserIdentity.Groups;
        IdentityReference translatedGroup = default(IdentityReference);

        foreach (IdentityReference g in groups) {
            translatedGroup = g.Translate(typeof(NTAccount));
            if (translatedGroup.Value.ToLower().Contains("desired group")) {
                inDBGroup = true;
                return 1;
            }
        }
    }
    else {
        return 0;
    }
}
查看更多
登录 后发表回答