Rishi
Rishi

Reputation: 321

Query AD users from outside the domain

I have an ASP .NET web application that is required to authenticate to and retrieve user lists from an Active Directory connection. The problem is the machine that is running the web server is part of a workgroup (NOT the domain that I am working with). I am able to authenticate to the AD by putting in the domain name but retrieving a user list is failing.

My question is, am I doing something wrong in trying to fetch AD users from outside the domain? If so, what can I do to rectify that? My code snippets are below:

 public bool IsAuthenticated(string username, string pwd)
 {
     try
     {
         validUser = adContext.ValidateCredentials(username, pwd, ContextOptions.Negotiate);
     }
     catch (Exception ex)
     {
         Logging.Instance.Log(Logging.Levels.Error, "Error authenticating user: " + username + " : " + ex.Message.ToString());
     }
     return validUser;
 }


public List<DirectoryEntry> GetAllUsers()
{
    try
    {
        userADlist = new List<DirectoryEntry>();
        Logging.Instance.Log(Logging.Levels.Message, "Finding all users for: "+adContext.ConnectedServer + " " + adContext.Container);
        using (PrincipalSearcher searcher = new PrincipalSearcher(new UserPrincipal(adContext)))
        {
            foreach (Principal result in searcher.FindAll())
            {
                userADlist.Add(result.GetUnderlyingObject() as DirectoryEntry);
            }
        }
    }
    catch (Exception)
    {
        throw;
    }
    return userADlist;
}

Upvotes: 1

Views: 5480

Answers (3)

brycepfrimmer
brycepfrimmer

Reputation: 51

Rainer Schaack has it right here. The credentials from the IsAuthenticated function will not be used for the bind to the AD in when GetAllUsers() is called. To which, one solution is to bind to the PrincipalContext with the username and password. There is a risk to putting credentials in a config or hard coding them. I want to clarify though that with the code above, these credentials would not be passed in clear text to/from the AD in a different domain.

The line to validate the credentials above is:

validUser = adContext.ValidateCredentials(username, pwd, ContextOptions.Negotiate);

The ContextOptions.Negotiate is important here. The documentation here and here explains that the Negotiate option uses Kerberos or NTLM. Both of which when you investigate do not pass the credentials using clear text.

Perhaps at the time of the post this was not the case. I didn't dig that deep to see. For those implementing a solution similar to this moving forward, this is important to understand.

Upvotes: 0

Rishi
Rishi

Reputation: 321

Thanks for your comments, I fully understand the risk of cleartext passwords.

I cannot use the suggested method of binding to the PrincipalContext with a username and password because I am hesitant to put it in a config file or hard code it.

The workaround I have employed that works is to add a domain user account as an Administrator on the non-domain server, then use that as the Application pool identity for my web application. This way, IIS inherently uses the account credentials to authenticate to the AD server and I get a list of users correctly.

I thank you for your help. Rishi

Upvotes: 0

Rainer Schaack
Rainer Schaack

Reputation: 1618

Your code does not show where adContext is created. I can only suspect:

In the working code (IsAuthenticated) you just check if the given credentials (user + pw) are correct.

But if you you call GetAllUsers these credentials are not "magically" reused, so your bind to the foreign AD fails.

You can use the constructor of PrincipalContextwhich takes user + pw. (https://msdn.microsoft.com/en-us/library/bb341016.aspx)

Also take a look at:

How does PrincipalContext login to domain server

Validate users of Remote Active Directory in C#

connect active directory using c#

However, as the comments suggest: it is not a good idea to use clear text passwords.

Upvotes: 2

Related Questions