views:

300

answers:

4

I have a web app (.NET 3.5) which is sending notifications by email to users. In order to do this, I search Active Directory to find each person's email.

At the moment, I am hardcoding my own username and password like so in order to search AD:

    Dim entry As New DirectoryEntry("LDAP://companyad", "myUsername", "myPassword", AuthenticationTypes.Secure)
    Dim srch As New DirectorySearcher(entry)
    srch.Filter = [String].Format("(&(objectClass=person)(sAMAccountName={0}))", "someOtherUsername")
    Dim result As SearchResult = srch.FindOne()

Now, obviously, this is not ideal and I don't want those credentials hardcoded. My web app is using Windows Authentication. It also uses impersonation (as the logged in user) to access files and SQL Server. Is there also a way for me to "impersonate" the logged in user in order to search AD?

EDIT 1

I thought I'd better explain why I chose this answer. The problem turned out to not be the multi-hop issue or kerberos as it seems I have set these up correctly.

I had recently changed my app to only allow access to a certain group through the web.config settings. I had previously been only allowing access to myself. I set up the group and added myself to it. I then removed the hardcoded credentials and attempted to run the app WITHOUT RESTARTING my computer.

According to my network admin, I would not be logged on under that new group until I restarted my computer which I think is what was causing my problem. So, Preet's answer is actually the most accurate as I just needed to pass the LDAP path to DirectoryEntry.

EDIT 2

I also needed to register a Service Principal Name.

I ran this:

setspn -A HTTP/[dns name of the site] [machine name]

on my development machine.

Thanks to everyone else for their answers.

A: 

Doesn't

Dim entry As New DirectoryEntry("LDAP://companyad")

work?

Preet Sangha
Unfortunately, no. I get this exception: "Type : System.Runtime.InteropServices.COMException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Message : An operations error occurred." Useful, huh?
Andrew
Check what it says in the event log.
Preet Sangha
A: 

Why not create a new user for this purpose alone? A user with only searching rights.

Shoban
I guess this option would be my last resort. Also, it is company policy for all passwords to be reset every month which would mean I would have to change password in the app every month.
Andrew
Ah!!! :) even we have the policy but exceptions are there for special cases.
Shoban
Haha, yes, if it comes to this then I hope my boss we be flexible enough to accommodate it.
Andrew
A: 

I set <identity impersonate="true"/> in my web.config and added the following code to my my page load event handler. It worked fine. Are you sure you are not dealing with a multi hop situation? In that case your app pool account needs to be configured for kerberos authentication to support impersonation in a multihop scenario. More info on this is here: http://support.microsoft.com/kb/329986

Response.Write(User.Identity.Name);
DirectoryEntry entry = new DirectoryEntry("LDAP://[mydomain.net]");
DirectorySearcher srch  = new DirectorySearcher(entry);
srch.Filter = string.Format("(&(objectClass=person)(sAMAccountName={0}))", "[user]");
SearchResult result = srch.FindOne();
Response.Write(result.Path);
Athens
A: 

If you wish to use the Windows logged in user account as the credentials against AD, you have to use the following:

public bool IsExistingUser() {
    DirectoryEntry de = new DirectoryEntry(Environment.UserDomainName)
    DirectorySearcher ds = new DirectorySearcher(de)
    ds.Filter = string.Format("((objectClass=user)(SAMAccountName={0}))", Environment.UserName)

    try
        SearchResult sr = ds.FindOne();
        if (sr != null && sr.DirectoryEntry.Name.Contains(Environment.UserName))
            return true;
    catch (DirectoryServicesCOMException ex)
    catch (COMException ex)
        throw new Exception("Can't find logged in user in AD", ex);

    return false;
}

Assuming this code would compile and run, it will verify whether the existing logged in user is known by your Domain Controller.

Impersonation is discouraged as it lets litteral password strings travel in your network. So, try to avoid it as much as possible.

EDIT Here's a pretty useful link for AD: Howto: (Almost) Everything In Active Directory via C# I found this post awesome!

Will Marcouiller