Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to use Active Directory with ASP.NET using LDAP?

Active Directory and ASP.NET

How to use Active Directory with ASP.NET using LDAP?

by  Glowworm27  Posted    (Edited  )
I went through many hoops to figure this out. There are many references on the web that talk about AD but very few of them actually provided me with any insight to the propper use of AD with ASP.NET web application.

Here is my problem...

I need to display the "REAL NAME" of the user that is using the web application, and NOT the "Domain USERNAME"
Display "George Oakes" NOT "DomainName\Goakes"

I can get the Domain\USERNAME by first setting the IIS Directory Security to Integrated Windows Authentication, and unchecking "Anonymous Access", then in the Web.Config File set the <authentication mode="Windows" />

then in Code use HttpContext.Current.User.Identity.Name
to get the Domain\Username

Now our company has two domains, Domain1, and Domain2
Each of the domains trusts each other, but to get the individual username, you must query the AD for the Domain the user exists in.

You can figure this out by looking at the DOMAIN in the Domain\Username, and then set the LDAP path accordingly

i.e.
Code:
Dim strUsername as String
Dim ADPath as String
Dim strRealName as String

strUserName = HttpContext.Current.User.Identity.Name
        If InStr(strUserName, "Domain1") Then
            strUserName = strUserName.Replace("DOMAIN1\", "")
            strADPath = "DC1.DOMAIN1.com"
        ElseIf InStr(strUserName, "DOMAIN2") Then
            strUserName = strUserName.Replace("DOMAIN2\", "")
            strADPath = "DC1.DOMAIN2.com"
        End If

In this code the strUserName looks like this "DOMAIN1\goakes"
So in the first part of the if statement I look for DOMAIN1 in the strUSername if I find it, then I need to strip it out of the username, because you cannot search for the user with the full DOMAIN\USername, only the Username. Then I Set the Active Directory to the Domain1 Server.

If the user is from Domain2, then it falls into the ELSEif Condition, and again, Strips out the DOMAIN from the username, and sets the Active Directory to the DOMAIN2 Server.

NOTE: in the LDAP PAth you can use the Domain Name , "LDAP://DOMAIN1" , or a Active Directory Server NAme for that domain, "LDAP://DC1.Domain1.com" either will work.

Next you need to set the DirectoryEntry object.
IN ASP.NET and VB.NEt by default the System.DirectoryServices namespace is not included in the references, you must manualy add this to your project. To do this in the Solution Explorer of Visual Studio .Net, Right-Click on References and Select Add Reference, and in the Add Reference Dialog box, select System.DirectoryServices.dll and click OK.

Then at the beginning of the ASPX Codebehind page add the IMPORTS System.DirectoryServices so you can use the namespace easier.

So your Code will look like this ...

Code:
IMPORTS System.DirectoryServices 

Public Class _Default
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents lblUserName As System.Web.UI.WebControls.Label
    Protected WithEvents Table1 As System.Web.UI.WebControls.Table
    Protected WithEvents Label1 As System.Web.UI.WebControls.Label
    Protected WithEvents Label2 As System.Web.UI.WebControls.Label
    
    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
               SetupSession()
    End Sub

Sub SetupSession()
Dim strUserName As String
Dim strRealName As String
Dim strADPath As String

strUserName = HttpContext.Current.User.Identity.Name
        If InStr(strUserName, "Domain1") Then
            strUserName = strUserName.Replace("DOMAIN1\", "")
            strADPath = "DC1.DOMAIN1.com"
        ElseIf InStr(strUserName, "DOMAIN2") Then
            strUserName = strUserName.Replace("DOMAIN2\", "")
            strADPath = "DC1.DOMAIN2.com"
        End If


        Dim Entry As DirectoryEntry = New DirectoryEntry("LDAP://" & strADPath, "DOMAIN1\GUEST", "GUESTPWD5")
        Dim Searcher As DirectorySearcher = New DirectorySearcher(Entry)
        Dim result As System.DirectoryServices.SearchResult

        Try

            Searcher.Filter = ("(anr=" & strUserName & ")")
            result = Searcher.FindOne()
            strRealName = (result.GetDirectoryEntry().Name).Replace("CN=", "").Replace("\", "")


        Catch ex As Exception
            Dim debug As String = ex.Message
        End Try

NOTE: another thing to point out is you need to supply a valid username and password to access active directory.

In my case because my two domain trust each other, a valid user on either domian can be used to access Active Directory. we used a guest account that can log onto both domains. I'm not entirely sure how much access the user account need, but I would guess that they need to be able to log into either domain at least.
i.e.
Dim Entry As DirectoryEntry = New DirectoryEntry("LDAP://" & strADPath, "DOMAIN1\GUEST", "GUESTPWD5")

Now the way this code is it will return the REAL NAME of the user accessing this web page, but it will be formated like this "Lastname, Firstname"

In the line strRealName = (result.GetDirectoryEntry().Name).Replace("CN=", "").Replace("\", "")

the result.GetDirectoryEntry().Name comes back as "CN=Lastname\, Firstname" so by using the replace functions I am able to strip out CN=, and the "\" from the username. If you set result.GetDirectoryEntry().Name to result.GetDirectoryEntry().Path, it will return something like this...
"LDAP://DC1.DOMAIN1.COM/CN=Lastname\,Firstname,CN=users, DC=DC1,DC=DOMAIN1,DC=COM"

'***Modified on 09/28/2004 ~GLO
Thanks to Atomicchip for this bit of insight into ADSI.
AtomicChip says that the correct use for the Searcher.filter is to use sAMAcountName instead of acr like I have. For readability I would agree with AtomicChip as anr doesnt realy tell you what it is right away..
for example...
Searcher.Filter = ("(sAMAccountName=" & strUserName & ")")

In my code
Searcher.Filter = ("(anr=" & strUserName & ")") "anr" is what I found on MSDN.Microsoft.com, either way works the same.

Another note from AtomicChip was instead of hacking up the GetDirectoryEntry().Name like I did in this piece of code
Code:
strRealName = (result.GetDirectoryEntry().Name).Replace("CN=", "").Replace("\", "")

You can query the "sn" and "GivenName" properties from AD. like this
Code:
strRealName = result.Properties("givenName")(0).ToString() & " " & result.Properties("sn")(0).ToString()

This was a much nicer and cleaner way to get the users "Real Name"

and Finaly AtomicChip notes that if your active directory is large you may want to "Load-up" only the data you wish to return, this reduces the load on Ad, and the amount of data being returned, thus making it faster. In my case all I wanted was the "sn", and the "GivenName" Properties from the AD.
here is what I ended up using...
Code:
Searcher.PropertiesToLoad.Add("sAMAccountName") ' // AD account name
            Searcher.PropertiesToLoad.Add("givenName") '; // user's first name
            Searcher.PropertiesToLoad.Add("sn") '; // user's surname

Many thanks to AtomicChip for his insight, and knowledge..
'***End of Modifications 9/28/2004 ~GLO
I hope that this FAQ is Usefull to someone.
Good Luck!
[cannon]
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top