简体   繁体   中英

How to find a User's Group with LDAP in C# Core 2

I am using C# Core 2 using Active Directory as the authentication method with Novell - I have got the verify user based on password section working, authenticating them if the username and password are correct in AD.

I want to get the user group of the logged in user, to add further security, in the same way [Authorize(roles="*")] would.

The below code is what I have so far, I know the connection is correct, but I cannot get any results in the SearchResults, it always returns as a count of 0.

Where am I going wrong? Not had any previous Active Directory exposure.

Search function :

    int searchScope = LdapConnection.SCOPE_BASE;
    string searchFilter = "(CN = " + username + ")";
    string searchBase = "OU=Users,OU=TOD,OU=Departments,DC=domain,DC=com";
    // folder structure Users/TOD/Departments/List of people

    // reading members of dynamic group could take long so set timeout to 10 seconds
    LdapSearchConstraints constraints = new LdapSearchConstraints();
    constraints.TimeLimit = 10000;

    #region connection
    string host = "mydomain.com";
    string un = "mydomain\\" + username;
    int port = 389;
    int version = LdapConnection.Ldap_V3;

    var conn = new LdapConnection();

    conn.SecureSocketLayer = false;
    conn.Connect(host, port);
    conn.Bind(version, un, pass); //parsed in through function params
    #endregion

    LdapSearchResults searchResults = conn.Search(
        searchBase,
        searchScope,
        searchFilter,
        null, // no specified attributes
        false, // return attr and value
        constraints);
      // always returns a search with 0 count

UPDATED:

I am getting LDAP connection errors intermittently, and on other occasions the search is brought back as empty - I don't know if this is to do with waiting but it will immediately hit the break point I set at conn.Disconnect() rather than any break points in the while loop.

[TestMethod]
    public void SearchForUserDepartentTest()
    {
        var users = new Dictionary<string,string>();
        var count = 0;

        string searchFilter = "(objectclass=*)";
        string searchBase = "OU=Departments,DC=domain,DC=com"; //ou=users, ou=TOD

        // reading members of dynamic group could take long so set timeout to 10 seconds
        LdapSearchConstraints constraints = new LdapSearchConstraints();
        constraints.TimeLimit = 10000;

        #region connection
        string host = "domain.com";
        string un = "domain\\doatemp2";
        string pass = "****";
        int port = 389;
        int version = LdapConnection.Ldap_V3;

        var conn = new LdapConnection
        {
            SecureSocketLayer = false
        };
        conn.Connect(host, port);
        conn.Bind(version, un, pass);
        #endregion
        try
        {
            LdapSearchResults searchResults = conn.Search(
                searchBase,
                LdapConnection.SCOPE_ONE,
                searchFilter,
                null, // no specified attributes
                false, // return attr and value
                constraints);

            while (searchResults.hasMore())
            {
            // doesn't hit in here intermittently
                count++;
                var nextEntry = searchResults.next();

                nextEntry.getAttributeSet();
                var attr = nextEntry.getAttribute("NAME");

                if (attr == null)
                {
                    users.Add("Distinguished Name", nextEntry.getAttribute("distinguishedName").StringValue);
                }
                else
                {
                    users.Add((nextEntry.getAttribute("SAMACCOUNTNAME") == null)? "NULL ACC Name " + count : nextEntry.getAttribute("SAMACCOUNTNAME").StringValue
                        ,(nextEntry.getAttribute("DISTINGUISHEDNAME") == null)? "NULL DN" + count : nextEntry.getAttribute("distinguishedName").StringValue);
                }                    
            }
        }
        catch (LdapException ldapEx)
        {
            ldapEx.ToString(); // ocassional time outs
        }
        catch (Exception ex)
        {
            ex.ToString();
        }
        conn.Disconnect(); // when run hits the break point here, missing out the anything in searchResults.hasMore()
    }

UPDATE 2:

Latest code.

[TestMethod]
public void SearchForUserDepartentTest()
{ 
    var users = new Dictionary<string,string>();
    var count = 0;

    string searchFilter = "(objectclass=*)";
    string searchBase = "OU=Departments,DC=domain,DC=com"; //ou=users, ou=TOD

    // reading members of dynamic group could take long so set timeout to 10 seconds
    LdapSearchConstraints constraints = new LdapSearchConstraints();
    constraints.TimeLimit = 30000;

    #region connection information
    string host = "domain";
    string un = "domain\\doatemp2";
    string pass = "";
    int port = 389;
    int version = LdapConnection.Ldap_V3;
    #endregion

    try
    {
        using (var conn = new LdapConnection { SecureSocketLayer = false })
        {
            conn.Connect(host, port);
            conn.Bind(version, un, pass);

            LdapSearchResults searchResults = conn.Search(
                searchBase,
                LdapConnection.SCOPE_SUB,
                searchFilter,
                null, // no specified attributes
                false, // return attr and value
                constraints);

            while (searchResults.hasMore())
            {
                count++;
                var nextEntry = searchResults.next();

                nextEntry.getAttributeSet();
                var attr = nextEntry.getAttribute("NAME");

                if (attr == null)
                {
                    users.Add("Distinguished Name", nextEntry.getAttribute("distinguishedName").StringValue);
                }
                else
                {
                    users.Add((nextEntry.getAttribute("SAMACCOUNTNAME") == null) ? "NULL ACC Name " + count : nextEntry.getAttribute("SAMACCOUNTNAME").StringValue, 
                        (nextEntry.getAttribute("DISTINGUISHEDNAME") == null) ? "NULL DN" + count : nextEntry.getAttribute("distinguishedName").StringValue);
                }
            }
        }
    }
    catch (LdapException ldapEx)
    {
        ldapEx.ToString(); // ocassional time outs
    }
    catch (Exception ex)
    {
        ex.ToString();
    }

    var check = users;
}

UPDATE 3: Using Core console application in case testing environment was causing adverse effects. With below code getting a readout of LdapConnection timeout 85

public static void SearchForUserDepartent() { var users = new Dictionary(); var count = 0;

string searchFilter = "(objectclass=*)";//string.Empty;
string searchBase = "OU=Users,OU=TOD,OU=Departments,DC=domain,DC=com";

LdapSearchConstraints constraints = new LdapSearchConstraints
{
    TimeLimit = 15000
};

#region connection information
string host = "dm1.domain.com";
string un = "domain\\doatemp2";
string pass = "password";
int port = 389;
#endregion

try
{
    using (var conn = new LdapConnection { SecureSocketLayer = false })
    {
        conn.Connect(host, port);
        conn.Bind(un, pass);

        LdapSearchResults searchResults = conn.Search(
            searchBase,
            LdapConnection.SCOPE_SUB,
            searchFilter,
            null, // no specified attributes
            false, // return attr and value
            constraints);

        while (searchResults.hasMore())
        {
            count++;
            var nextEntry = searchResults.next(); // hits and then goes to timeout

            nextEntry.getAttributeSet();
            Console.WriteLine("Distinguished Name:" + nextEntry.getAttribute("distinguishedName").StringValue);
            Console.ReadKey();
        }
    }
}
catch (LdapException ldapEx)
{
    Console.WriteLine(ldapEx.ToString()); // ocassional time outs
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}
    foreach(var u in users)
    {
        Console.WriteLine("Key:" + u.Key.ToString() + " | Value:" + u.Value.ToString());
    }
Console.ReadKey();
}

LdapSearchResults Count always 0, you should use .hasMore() to get value of your searching

Try somethink like this

                var users = new HashSet<string>();
//My domain have 4 DC's
            LdapSearchResults searchResults = conn.Search(
                "CN=Users,DC=z,DC=x,DC=c,DC=v",//You can use String.Empty for all domain search. This is example about users
                LdapConnection.SCOPE_SUB,//Use SUB
                "(mail=*@somemail.com)",// Example of filtering with *. You can use String.Empty to query without filtering
                null, // no specified attributes
                false // return attr and value
                );

            while (searchResults.hasMore())
            {
                var nextEntry = searchResults.next();
                nextEntry.getAttributeSet();
                var attr = nextEntry.getAttribute("mail");

                if (attr == null)
                {
                    users.Add(nextEntry.getAttribute("distinguishedName").StringValue);
                }
                else {
                    users.Add(nextEntry.getAttribute("mail").StringValue);
                }

            }

for better querying use ActiveDirectory Users and computers. there are has attribute editor witch can provide all information about DC,CN,OU and attrs

Also more info at here and here

UPDATE: as official documentation says:

SCOPE_BASE:Used with search to specify that the scope of entrys to search is to search only the base obect.

SCOPE_ONE:Used with search to specify that the scope of entrys to search is to search only the immediate subordinates of the base obect.

SCOPE_SUB:Used with search to specify that the scope of entrys to search is to search the base object and all entries within its subtree.

SCOPE_SUB that means that you can use searchBase without full entry path or use string.Empty to full domain search

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM