Troubleshooting Authentication Problems on ASP Pages

If you have an application that is working from a Windows-based or command line application, but is not working when you transfer it to an ASP.NET application, the problem likely pertains to security. The System.DirectoryServices namespace uses Active Directory Services Interfaces (ADSI) to contact discrete directory services through different ADSI providers. This topic assumes that you, the application designer, want the directory to be contacted under the security context of the ASP.NET Web user. If you do not want to do that, or you do not want to perform the resolutions that are listed in this topic, you can work around these problems by passing credentials to your DirectoryServices code through the class constructor, or by using the Username and Password properties.

What is a Primary Token?

Active Directory Domain Services relies on the security mechanism of the Windows 2000 server. To access most data in Active Directory Domain Services, provide credentials to the Windows 2000 server when requesting Active Directory Domain Services data. The credentials you provide must be in a primary token, which just means that the IIS server has a password, not just a hash of the password, to pass to Active Directory Domain Services.

If the code works when you browse to it from the development computer that is a Web server, but the code does not work when other Web clients access the pages, you may receive an error message similar to the following.

"Failed: System.Runtime.InteropServices.COMException 
(0x80005000): Unknown error (0x80005000) at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)"
"The specified directory service attribute or value does not exist" 

This error is an indication that you do not have a primary token.

How to Acquire a Primary Token

When the Web.config file is set to identity impersonate="true"/ and authentication mode="Windows", use the Anonymous account with the following settings:

To acquire a token using an Anonymous account

  1. On the ASPX page, set the security mechanism to Anonymous only.

  2. Clear the Allow IIS to control the password check box.

  3. Set the Anonymous account to be a domain user.

When Web.config and Machine.config are set as follows:

To acquire a token using configuration settings

  1. When Web.config is set to identity impersonate="false"/ and authentication mode="Windows".

  2. When Machine.config is set to processModel username=<domain>\<username>,password=<password>. If identity impersonate="false"/ in the Web.config file, the credentials of the Base process are used. When you supply a domain user and password, you enable IIS to pass a primary token to AD DS.

Double-Hop Issue

The double-hop issue occurs when the ASPX page attempts to use resources located on a server that is different from the IIS server. In our case, the first "hop" is from the web browser client to the IIS ASPX page; the second hop is to Active Directory Domain Services. Active Directory Domain Services requires a primary token. Therefore, the IIS server must know the password for the client to pass a primary token to Active Directory Domain Services. If the IIS server has a secondary token, the NTAUTHORITY\ANONYMOUS account credentials are used. This account is not a domain account and has very limited access to Active Directory Domain Services.

The double-hop using a secondary token occurs, for example, when the browser client is authenticated to the IIS ASPX page by using NTLM authentication. In this example, the IIS server has a hashed version of the password as a result of using NTLM. If IIS turns around and passes the credentials to Active Directory Domain Services, IIS is passing a hashed password. Active Directory Domain Services cannot verify the password so it uses NTAUTHORITY\ANONYMOUS LOGON for authentication.

If your browser client uses Basic authentication to authenticate to the IIS ASPX page, the IIS server has the client password and can make a primary token to pass to Active Directory Domain Services. Active Directory Domain Services can verify the password and authenticate the domain user.

Troubleshoot the Double-Hop Issue

Use one of the following methods to troubleshoot the double-hop issue.

To quickly determine whether this is a permissions issue, do the following:

To check for a permissions problem

  1. Set the ASPX page security mechanism to use Basic only.

  2. Use a client to browse to the ASPX page, and then provide domain credentials when prompted.

    If this works, the double-hop issue is likely the problem.

Another good troubleshooting test for any IIS ASPX issue when you access Active Directory Domain Services involves taking your ASPX code out of the IIS environment and running it as a script file on the IIS server itself. To use this method, do the following:

To test your code

  1. Log on to the IIS server as the domain account that your browser was trying to use, and then run the code.

    This test removes the IIS server from the environment and helps troubleshoot the problem.

  2. To determine whether this is a double-hop issue, turn on auditing for directory service objects. After you turn on logging, events are written to the security event log.

    If this is your issue, you can find events in the security event log that are similar to the following:

    Event Type: Success Audit
    Event Source: Security
    Event Category: Directory Service Access 
    Event ID: 565
    Date:  3/27/2002
    Time:  3:21:41 PM
    User:  NT AUTHORITY\ANONYMOUS LOGON
    Computer: TESTDC
    Description:
    Object Open:
      Object Server: DS
      Object Type: user
      Object Name: CN=Users,DC=corp,DC=com
      New Handle ID: 0
      Operation ID: {0,68019232}
      Process ID: 264
      Primary User Name: TESTDC$
      Primary Domain: TESTDOM
      Primary Logon ID: (0x0,0x3E7)
      Client User Name: ANONYMOUS LOGON
      Client Domain: NT AUTHORITY
      Client Logon ID: (0x0,0x40DE417)
      Accesses  READ_CONTROL 
    
      Privileges  -
    
     Properties: 
    

    Note

    The directory service has been contacted as the anonymous user. This is because the credentials of the Web user cannot be correctly conveyed to the directory service.

ASP.NET Base Account

By default, all ASP.NET applications run under the base process account, MACHINENAME\ASPNET. This is a local account that does not have access to objects in Active Directory Domain Services. To access Active Directory Domain Services by using the credentials that are passed to IIS, you must modify your Web.config file to contain the parameters identity impersonate="true" and authentication mode="Windows" . The presence of these two parameters causes ASP.NET to run the code under the credentials that are passed to it by IIS.

Note

This is similar to how classic ASP currently works. A High-Isolated or Out-of-Process (OOP) application is actually running in a separate DllHost process. DllHost's base process is IWAM_machinename. When calls are made to this OOP, it impersonates the user who was authenticated by IIS. With ASP.NET, pages will run in a separate process also, that process being Aspnet_wp.exe. By using the identity impersonate tag, the application designer controls whether that impersonation is performed.

Error That You May Receive If The ASP.NET Base Account Is Not Set Correctly

If the ASP.NET Base account is not set correctly, you may receive one of the following error messages:

Cannot contact the specified domain or domain does not exist
Logon Failure: Unknown Username or bad password

Troubleshoot ASP.NET Base Account

To troubleshoot this problem, check for the following issues.

  • If you have modified your Web.config file to use impersonation, but your DirectoryServices code does not succeed and you receive the same errors (for more information, see errors mentioned earlier in this article), the problem is probably caused by a default behavior in IIS. By default, the new virtual directory setup in IIS has Anonymous Authentication turned on. To resolve this, open Internet Services Manager and modify the authentication methods of the virtual directory to clear the Anonymous Authentication check box.

  • Although you call Invoke for SetPassword (or for another method that is exposed) on the underlying ADSI interfaces, and you receive the

    The Active Directory property cannot be found in the cache
    

    message, the error number that is returned is not 0x8000500D. The expected behavior is that error number 0x8000500D is returned with this description.
    For example:

    COMException (0x80020006): The Active Directory property cannot be found in the cache
    

    The confusion is that the cause of this error, as indicated by the error number, may not correspond to the error description. The cause of this error should be identified by the error number, and not by the description. Generally, you can expect the resolution to your problem to be determined by the error number, not by the description. In this example, the error number corresponds to DISP_E_UNKNOWNNAME.

  • If your IIS server is running on a Domain Control or Backup Domain Controller, the default base account may not work and you may receive errors.

  • If your base IIS server does not have rights to read, execute, and list on the root Web site, you receive an error when you browse to a Web page.

ADSI Schema Cache

ADSI tries to cache the schema from Active Directory Domain Services. The schema cache is used to determine how to read the attributes out of the attribute cache. If ADSI cannot cache the schema, it uses a V2 version of the schema. The V2 version of the schema contains a very small set of attributes.

ADSI will try to cache the schema only one time per process. In Windows 2000, ASP.NET runs under a single aspnet_wp.exe process. This means that the schema will not be cached again until the IIS service is shut down and restarted.

Subsequent Schema cache access may depend on the user rights of the first user who runs an ASP.NET page that uses ADSI on that server.

In a typical scenario, an administrator notices that the application works by launching a Web browser locally. The Web site is then made live and works for a period of time until the server is restarted or Web services are restarted.

At this point, the ASP.NET application stops working, because ADSI did not cache the schema correctly. This may happen when the first user to access the Web site cannot establish the credentials to correctly cache the schema. This is a likely scenario when a user suffers from the double-hop problem described earlier in this article. You may not quickly realize that this has happened because you may not see a Permission Denied error message or a Property not Found in Cache error message. This may be due to the method that was used to install Active Directory Domain Services. When the first domain controller in the domain is promoted, the DCPromo Wizard asks whether the Domain should be compatible with Windows NT 4 or with only Windows 2000. If you accept the default of Compatible permissions with NT4, the security principal EVERYONE is added to the Pre-Windows 2000 Compatible Access built-in group. This is significant because, by default, the Pre-Windows 2000 Compatible Access group has List Contents and Read All Properties permissions on many objects in the directory. Because the Anonymous user will access the directory service as EVERYONE, that anonymous user will get many attributes returned in a query and loaded into the attribute cache.

The schema that ADSI uses is stored in the cn=Aggregate object in the schema namespace. Neither the Pre-Windows 2000 Compatible Access built-in group nor the Everyone principal have permissions on this aggregate object. Therefore, schema information is not accessible. The result is that there is a property in the attribute cache that was retrieved from the server that ADSI does not understand. Because ADSI cannot determine the data type, you receive the error that is mentioned in the next paragraph.

ADSI Schema Cache Error

You may receive errors. After you restart the server, the Web application does not respond, and you may also receive the following error message:

0x8000500C, "The property in cache cannot be 
converted from native datatype"

This error indicates ADSI is not correctly caching your Active Directory Domain Services schema.

Correcting an ADSI Schema Cache Problem

  • If the registry keys are present, delete them, stop and restart IIS, and then browse to the Web page.
  • If the key is not created or the file is not written, either you do not have the permissions to download the schema cache from the server, or you do not have the permissions to write the file or create the registry key. If they are written, you can expect the page to work until the next time that IIS restarts. To resolve this, you must resolve the double-hop issue.

See Also

Reference

System.DirectoryServices
DirectoryEntry

Concepts

Active Directory Domain Services Authentication from ASP .NET

Send comments about this topic to Microsoft.

Copyright © 2007 by Microsoft Corporation. All rights reserved.