1

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;
}
Rishi
  • 321
  • 2
  • 6
  • 17
  • take a look at some of the suggestions located here http://stackoverflow.com/questions/1212138/how-do-i-authenticate-against-active-directory-from-asp-net-web-service-code – MethodMan Mar 23 '15 at 19:00
  • Thanks, @MethodMan. I understand the reason why cross-domain communication might be limited. I am actually able to transmit the password over cleartext to authenticate, but it is the retrieval of user lists that fails. I also get that there might not be a better implementation, but in order to convince the customer, I need some "ammunition" so to speak. Is there some official documentation that you can point me to? – Rishi Mar 23 '15 at 19:18
  • passing password over cleartext is a definite red flag hope you know that.. sounds like you need to come up with a secure method of logging in – MethodMan Mar 23 '15 at 19:22
  • I do know that, and I clearly communicated that as a potential problem. This application is going to reside on the local intranet for the customer so it boiled down to them not wanting to pay for development time anymore than the bare minimum. What I don't get is why authentication works if the server is not on the domain, but retrieving user lists does not. – Rishi Mar 23 '15 at 19:27
  • will the individuals whom are wanting to access data from outside the dmz could you create a webservice and then as part of the service have a guid or some uniqueId that they use to get the data? and only give the key to those whom will consume the web service.. – MethodMan Mar 23 '15 at 19:33

3 Answers3

2

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.

Community
  • 1
  • 1
Rainer Schaack
  • 1,558
  • 13
  • 16
0

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

Rishi
  • 321
  • 2
  • 6
  • 17
0

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.