If you have a website using ASP pages or asp.net pages, and you want to integrate user management with active directory, you’ll have a lot of extra technology that you need to make yourself known with. 

 

Add this article to my Live favorites

 

What you mostly would do, is disable anonymous web access, and have users login, using credentials stored at Active Directory.

 

But unfortunately, IIS, Internet Information Server, on Windows 2003 and 2000, does map only the current logged on user through an NT4 domain format, which looks like ‘DOMAIN\johnd’ retrieved from Request.ServerVariables(“LOGON_USER”) or Request.LogonUserIdentity.Name, will equal exactly that name in NT 4 format. You can also logon to an IIS website using a user principal  (in AD, this the attribute userPrincipalName like 'johnd@domain') but we need to be sure that the identity -always- can be handled, no matter what syntax is given by the user at logon.

 

So from there you need to translate the NT4 name to a distinguished Name (dn is like  “cn=itsme,cn=users,dc=nwtraders,dc=msft”)  that is suitable for Active Directory.

 

Now comes an often made ‘trick’ which is obviously slow (see for a listing, completely below)! 

One could do a Directory Search on sAMAccountName=’johnd’ and get the active, logged on user and its active directory record. <- don't do this!

 

A very fast method would be as follows.
note: this is assuming that you are using the DotNet framework version 2.0 and c#. The very same effective code could be written for Vb.Net.

 

 

protected void Page_Load(object sender, EventArgs e)

{

// identical to Request.LogonUserIdentity but using a static method instead of a Page property
//WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent();

wi = System.Security.Principal.WindowsIdentity.GetCurrent();

        WindowsIdentity wi = Request.LogonUserIdentity;

        DirectoryEntry dir = new DirectoryEntry("LDAP://<SID=" + SidToHex(wi.User) + ">");

        

        dir = new DirectoryEntry("LDAP://" + (string)dir.Properties["distinguishedName"][0], null, null,

            AuthenticationTypes.Secure |

            AuthenticationTypes.ReadonlyServer);

 

 

//Now you got ‘dir’ at your disposal and you can read the current users profile information (for instance)!

 

}

 

To get Request.LogonUserIdentity initialized after a browser logon to your aspx pages, with the correct user-logon-info,

configure web.Config as follows so that it contains at least the configuration seen below.

 

web.Config

<?xml version="1.0" encoding="utf-8"?>

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

    <system.web>

            <compilation defaultLanguage="c#" debug="true">

            <assemblies>

            <add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

                  <add assembly="System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

            </assemblies>

 

        <authentication mode="Windows" />

        <identity impersonate="true"/>

    </system.web>

</configuration>

 

    /// <summary>

    ///  needed for Windows 2000 compatibility

    /// Windows 2003 can bind using a S-1-xx-x-xx-xxx- format

    /// </summary>

    /// <param name="sid"></param>

    /// <returns></returns>

    private static string SidToHex(SecurityIdentifier sid)

    {

        int binLength = sid.BinaryLength;

        byte[] bt = new byte[binLength];

        sid.GetBinaryForm(bt, 0);

        System.Text.StringBuilder retval = new System.Text.StringBuilder(binLength * 2, binLength * 2);

        for (int cx = 0; cx < binLength; cx++)       

            retval.Append(bt[cx].ToString("X2"));

        return retval.ToString();

    }

Bad performing often used code, not to be used!

string ldapPath = "LDAP://" + userDomain;
DirectoryEntry rootEntry = new DirectoryEntry(ldapPath);
using (DirectorySearcher ds = new DirectorySearcher(rootEntry, "(samAccountName=" + userName + ")"))
{
            SearchResult result = ds.FindOne();
            if (result != null)
            {
                        ResultPropertyValueCollection resultValues = result.Properties["displayName"];
                        if (resultValues.Count > 0)
                        {
                                    Label1.Text = (string) resultValues[0];
                        }
                        else
                        {
                                    Label1.Text = "No display name"; 
                        }
            }
}