views:

1623

answers:

4

I use a console application to write some test code:

    /// <summary>
    /// Returns AD information for a specified userID.
    /// </summary>
    /// <param name="ntID"></param>
    /// <returns></returns>
    public ADUser GetUser(string ntID)
    {            
        DirectorySearcher search = new DirectorySearcher();         
        search.Filter = String.Format("(cn={0})", ntID);

        search.PropertiesToLoad.Add("mail");
        search.PropertiesToLoad.Add("givenName");
        search.PropertiesToLoad.Add("sn");
        search.PropertiesToLoad.Add("displayName");
        search.PropertiesToLoad.Add("userPrincipalName");            
        search.PropertiesToLoad.Add("cn");

        SearchResult result = search.FindOne();

        return new ADUser(result);
    }

And this worked fine from the console app. However, when I moved it to an ASP.NET application, I received an error message about not knowing the correct domain.

Is there a trick I am missing for accessing AD when running on the ASPNET account?

EDIT: Passing just a LDAP://domain connection string isn't enough, as it wants an actual login/password. Because this runs on a local account on a machine, I'm not sure what AD L/P to use. Can I delegate the accessing users account to this somehow?

EDIT #2: When trying to use identity impersonation, I get a DirectoryServicesCOMException with:

The authentication mechanism is unknown.

+1  A: 

Yes. You need to give it a directory connection string. A console app (running as you) runs with your credentials, including directory access. An ASP.NET app runs with the ASPNET user's credentials, which are local to the system the app is running on, not directory-global.

DannySmurf
+1  A: 

Alternatively you could specify identity impersonate=true in the web.config and the request to Active directory will be sent as the calling user instead of Machine\ASPNET

Edit: If you are getting the authentication error see PIPTHEGEEK's post you will have to trust your web server for delegation, however be careful with trusting for delegation (since it opens another can of worms for security types). You have to allow the web server to pass the credentials of the current user to AD.

If possible, go to AD properties for the computer, select the delegation tab, and select "Trust this computer for delegation to any service (Kerberos Only)

See if that works. If it does, you can further fine grain the permissions by using the third option which states

"Trust this computer for delegation to specified services only"

Then select "Use Kerberos Only"

and in the "services to which this account can present delegated credentials", add the relevant service information.

RandomNoob
+1  A: 

If its an intranet application that uses windows authentication, then you can wrap your AD call in a impersonation-context of the user.

Something like:

using (((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate())
{
 // Do your AD stuff here
}
Tom Jelen
This is being called from a library, not a page, so how would I access the user?
FlySwat
I don't have a visual studio near me to test it. But if my memory serves me well, then System.Threading.Thread.CurrentPrincipal.Identity should contain the exact same Identity.
Tom Jelen
Edit #2 makes me think that System.Threading.Thread.CurrentPrincipal.Identity.Name does not hold the expected domain\username, is that correct?
Tom Jelen
Actually, I can't cast System.Thrading.Thread.CurrentPrincipal.Identity to WindowsIdentity. I was just trying using "impersonate=true" in web.config.
FlySwat
Ah okay. Sounds like you haven't turned windows authentication on for the web-app in IIS then. If it is on, then I am out of ideas.
Tom Jelen
It is because delegation isn't enabled. I have tried to outline the process in my answer, if you want more detail then update your question and i will do my best.
pipTheGeek
+1  A: 

The easiest way around this is to make your web application pool run as a domain account that has the required access. This avoids you having to manage the secure storing of a password. Don't forget to make the account a member of the IIS_WPG local group. If you do decide to use impersonation you will have to configure Kerberos delegation as well as changing the ASP.NET configuration to impersonate. This will involve making the application pool run as a domain account, granting that domain account permission to delegate credentials (the delegation tab of the account properties in the AD users and computers MMC). Then ensuring that the website is set to use negoiate in the metabase (this is the default on IIS6, not sure about other versions) and registering an SPN for the new domain account.

Edit: Your 'Unknown authentication' error sounds like mis-configured delegation. Check that the account your app pool is running as is trusted for delegation, that IIS is set to use ONLY windows authentication and that a valid SPN is registered for the app pool identity account.

pipTheGeek