Performing Web Authentication and Administration with LDAP
page 1 of 1
Published: 11 Mar 2005
Unedited - Community Contributed
Abstract
In this article, I will cover how to authenticate a user/password pair in ASP.NET with an LDAP server, how to determine which directory a user is located in (if the Directory Server contains more than one directory), how to add new users, as well as how to handle general maintenance of the users (additions, deletions, and modifications).
by Lance Robinson
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 73368/ 61

Basics of Using IP*Works! LDAP component to communicate with an LDAP directory server.

In order to accomplish all of this I'm going to use the LDAP component of the IP*Works! .Net Edition. While there are many different editions of IP*Works! to choose from, including IP*Works! SSL if you need to securely communicate with an SSL-Enabled LDAP server, I have chosen to use the IP*Works! .Net Edition for simplicity. 

Section 1: The Basic Login

First things first - I need a login form for the users to enter a userid and password. On the form, I'll drop textboxes and labels for a "User ID" and "Password" to be submitted by the user, as well as a "Login" button for the user to click.

I'll add some code to bLogin.Click so that if the button is clicked, the authentication of the user will take place. To do this I'll perform a search for a UID (UserID) that matches the login name provided by the user on the form. I'll need to point the LDAP object to the LDAP server, provide a base DN on which to perform the search (see DSE Information, Section 2, for more details), and call the Search method with the search filter for this particular User ID.

 
Private Sub bLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bLogin.Click 
     Ldap1.ServerName = txtServer.Text 
     Ldap1.DN = "OU=Users,O=Server" 
     Ldap1.Timeout = 10 'a timeout > 0 will make the component behave synchronously 
     Ldap1.Search("uid=" + txtUserID.Text) 

NOTE: Active Directory (and some others, if they are configured in this way) require an explicit Bind before you can browse or modify the directory.  If you are using such a server, simply set a DN to bind with, a password (if applicable), and call the Bind method prior to using the code above.

Now, the SearchResult event of the LDAP component will fire with any search results received from the server. The SearchComplete event will fire when all of the results have been received, followed by the Result event, which will let me know if the Search finished with no errors or not (The Result event fires for every LDAP method, like Add, Delete, and Modify). After the Result event fires the ResultCode, ResultDescription, and ResultDN properties will contain the values of the last communication from the LDAP server. ResultCode and ResultDescription contain the same information that comes in the Result event. ResultDN contains the DN of the last result received - in this case, the last search result.

After the Search, I'll examine the ResultDN. If its empty, display an error message and exit.

 
     If Ldap1.ResultDN = "" Then 
          TextBox1.Text += "User Not found." 
          Exit Sub 
     End If 

If the ResultDN is not empty, I know that the Search succeeded, and the User I searched for does exist. The next step will be to attempt to authenticate this user with the password they provided. Important: In order for this to work, the entry MUST have a userPassword attribute. If there is no userPassword attribute for this DN, the authentication will always fail.

 
     Ldap1.DN = Ldap1.ResultDN 
     Ldap1.Password = txtPassword.Text 
     Ldap1.Bind() 
     If Ldap1.ResultCode = 0 Then 
          TextBox1.Text += "Success! You have been validated." + vbCrLf 
     Else 'login result was not "OK" 
          TextBox1.Text += "Error: " + Ldap1.ResultDescription + vbCrLf 
     End If 
End Sub 

Section 2: Which Directory? (Root DSE Searches)

Its possible for an LDAP server to contain more than one directory. For example, a directory for customer/client contacts, and a directory for employees. Normally the developer will know what these are ahead of time, but not always. So if I want to have the same login interface for both of these groups of people, and I do not know what the base DN's are, I'll need a way to determine exactly which base DN's to perform the search against. Each directory on the server will have a unique base DN. For example, on my server, the customer/client contacts directory base DN is:

 ou=People, O=Server

The employee directory has a base DN of:

 OU=Users, O=Server

If I don't know what these are - how can I determine them programmatically? This is one of the things that can be resolved by the root DSE (Directory Specific Entry) search. This is information that all LDAP servers will provide so that clients can have access to attributes of the server itself. Some of this information can be quite useful. For one example - each LDAP server can actually contain several different directories. One of the DSE Attributes is called "namingContexts", and this attribute is a list of base DN's (one for each directory) that one can access on this particular server. DSE Information will also tell you which versions of the LDAP protocol the server can understand.

A DSE search requires several attributes:

 Blank DN
 Search Filter of "objectClass=*"
 Search Scope of "Base"

This can be done with the LDAP component, like so:

 
ldap.ServerName = SERVERNAME 
ldap.DN = "" 
ldap.SearchScope = ssBaseObject 
ldap.Search "objectClass=*" 

The search result of a DSE search will not be like others - where I am searching for a particular DN. The only thing returned by this search will be attributes of the server, and these will arrive in the attribute property arrays of the LDAP component. Specifically, the AttrType() array will contain the type of each response attribute. The AttrValue() array will contain the corresponding values. AttrCount is the total number of attributes returned by the server. In this case, I am only interested in the namingContexts attributes, so that I can see exactly which base DN's I have on this server. I'll pick these out and write them.

 
Dim foundnamingcontexts = false 
For i = 0 To LDAP.AttrCount - 1 
     'this line prints out ALL attributes 
     'Response.Write("ATTR " + ldap.AttrType(i) + " = " + ldap.AttrValue(i) + "<br>") 
     If ldap.AttrType(i) = "namingContexts" Then 
          foundnamingcontexts = true 
          Response.Write("namingContexts: " & ldap.AttrValue(i) & "<br>") 
          mybaseDN = ldap.AttrValue(i) 
     Elseif ldap.AttrType(i) = "" And foundnamingcontexts = true Then 
          Response.Write("namingContexts: " & ldap.AttrValue(i) & "<br>") 
     Else 
          foundnamingcontexts = false 
     End if 
Next 

The above for loop becomes a little more complicated than you might imagine. The first instance of the namingContexts type in the attribute arrays is of type "namingContexts". But for subsequent attributes of the same type, which arrive one after the other, the server doesn't specify that type, but just leaves the type as empty string. In other words, in order, the server sent attributes like so:

 Type: sometype      , Value: sometype value
 Type: namingContexts, Value: dc=siroe, dc=com
 Type:               , Value: dc=Server                
 Type:               , Value: dc=Netscape, dc=com
 Type: someotherType , Value: someothertype value
 Type:               , Value: someothertype value 

So "dc=siroe, dc=com", "dc=Server", and "dc=Netscape, dc=com" are all namingContexts attributes, even though the second two have empty string as the type.

Section 3: Add New User

Now I've got a working login page for a website, but what happens when someone new drops by and wants to join or create a login? I need to programmatically add them to the LDAP server so that they can authenticate themselves.

The information that I'll need from the user is of course a UID (loginname) and a password. Just for demonstration, I'll also set a description attribute for the user. If you want other information - go for it, but keep in mind that the LDAP server allows only specific attribute types, and you'll need to stick with those. This shouldn't be a problem because there are many defined: address, phone number, description, and many others for you to use. See your server documentation for a full list.

When the user submits this information, I'll need to setup the DN and attribute arrays for this new LDAP entry first.

Before I set the DN - I need to know what base DN to add this person to. This is commonly something like "ou=People, O=Server". If you are unsure about this DN, please consult your server documentation, or browse the directory until you find the tree where you want to add the entry and find its DN. Once I have the DN (ie "ou=People, O=Server") I'll want to modify it to create our new users dn. To do this, I just add their UID to the beginning of it. If the users loginname is "SJenkins", I can set the DN = "uid=SJenkins, ou=People, IO=Server".

 
baseDN = "ou=People, O=Server" 
ldap.DN = "uid=" + Request("loginname") + ", " + baseDN 

Every LDAP entry is required to have a set of "objectClass" type attributes. For a person, these are:

 type = objectClass, value = top
 type = objectClass, value = Person
 type = objectClass, value = organizationalPerson
 type = objectClass, value = inetorgperson

So before I add this new DN to the server, I'll need to set some base attributes, which will be required by the server. I do this using the AttrType() and AttrValue() arrays. Below I'll simply set a description, the UID and userPassword.

 
ldap.AttrCount = 7 
ldap.AttrType(0) = "objectClass"
ldap.AttrValue(0) = "top" 
ldap.AttrType(1) = "objectClass" 
ldap.AttrValue(1) = "Person" 
ldap.AttrType(2) = "objectClass" 
ldap.AttrValue(2) = "organizationalPerson" 
ldap.AttrType(3) = "objectClass" 
ldap.AttrValue(3) = "inetorgperson" 
ldap.AttrType(4) = "description" 
ldap.AttrValue(4) = "New Account" 
ldap.AttrType(5) = "uid" 
ldap.AttrValue(5) = txtUserID.Text 
ldap.AttrType(6) = "userPassword" 
ldap.AttrValue(6) = txtPassword.Text 

NOTE: Active Directory will only allow you to create a new entry with the objectClass attributes. After the new entry is added, you can go back and add new attributes via the Modify method (See section 4 for Modify sample).

Voila! Now I have all of this new users attributes set up including his uid and password. I have his DN set. Now all thats left to do is add him to the server.

 ldap.Add()

SJenkins will now be able to login with his password via the method outlined in Section 1.

Section 4: General Maintenance

Any administrator needs to have a method of manually adding, deleting, or modifying user accounts under their control. By using LDAP as an authentication and directory tool, one can perform general maintenance on these accounts by hand, in person, on the actual server itself. However, with this LDAP component, this could also be done via the same website. This would allow website administration to take place remotely.

I've already covered adding new accounts. Deleting and modifying accounts are equally as simple.

In order to delete an account - all I need to do is set the DN for that account and use the Delete method.

ldap.DN = "uid=SJenkins, ou=People, dc=Server" 
ldap.Delete 

What if I don't want to delete the account, I just want to deactivate it? Let's say I want to still have a record that this account exists, but I don't want the user to have login access any longer. To do this, I could use a description attribute that specifies account status. When the user attempts to login, I can check this attribute to verify that the user has login rights. When I added "SJenkins" to the directory, I gave his description type attribute the value of "New Account". Now if I want to suspend this account, I could change this description attribute to "Suspended". To do this I'll need to modify the existing attribute. The LDAP component includes a Modify method for doing this. The Modify method can perform different kinds of attribute modifications: Add attribute, Delete attribute, and Replace attribute. Since the description attribute already exists, I'll use the Replace option. This is defined in the AttrModOp() array. Here, I just have 1 attribute that I want to replace. So I'll set the AttrCount to 1, the first (0 index) element of the AttrType() array to the type I am looking for (description), the zeroth element of the AttrValue() array to the new value for this attribute, and the first (0 index) element of the AttrModOp() array to 2 (replace). Then I'll just call the Modify method.

ldap.AttrCount = 1 
ldap.AttrType(0) = "description" 
ldap.AttrValue(0) = "Suspended" 
ldap.AttrModOp(0) = 2 'Replace 
ldap.Modify() 

After this, if I examine the description attribute for "SJenkins", it will have a value of "Suspended" instead of "New Account". If I wanted to delete/add the attribute type description of the value "Suspended", I would use the same method, except I would set AttrModOp() to 0 or 1 (Add or Delete) instead of 2 (Replace).



User Comments

Title: LDAP Authentication Classic ASP   
Name: Franco
Date: 9/8/2010 2:49:56 AM
Comment:
Thanks for this.
Can the author email an ASP classic version for authenticating/querying against LDAP?
Thanks in advance
Franco
franco19969@gmail.com
Title: LDAP Authentication Classic ASP   
Name: al
Date: 4/19/2010 12:32:02 PM
Comment:
Can the author email an ASP classic version for authenticating/querying against LDAP?
Thanks in advance
al
a_santora@yahoo.com
Title: LDAP Authentication - Lotus Notes Application From .net   
Name: Mani
Date: 1/5/2009 4:25:30 AM
Comment:
HI ,

Can any one help me , to make LDAP Authentication using .net with Lotus notes application
Title: asp classic version pls   
Name: Rob
Date: 12/16/2008 10:15:25 AM
Comment:
Could you send me the CLASSIC ASP example of this too pls?

rob.uijtdehaage@alliance-healthcare.nl
Title: asp classic   
Name: ronald
Date: 10/30/2008 1:43:24 AM
Comment:
Hi Lance,

Could you send me the CLASSIC ASP example of this?

rcornelisz@yahoo.com

Thank you
Title: Retrive email by using userid   
Name: Rama krishna Tamanala
Date: 4/18/2008 5:21:25 AM
Comment:
hi,

I am trying to find to get email address by giving company userid(123) in one textbox.

Note:- i am sending userid(123) only and nothing than else.
Title: Email   
Name: Lance
Date: 1/19/2008 1:26:56 AM
Comment:
To get the email, just get the "mail" attribute. With IPWorks v8 (the current version is v8, but note that this older article was initial written with ipworks v6), that would look like this:

Ldap1.DN = "OU=Users,O=Server"
Ldap1.Timeout = 10
Ldap1.Attributes.Clear();
Ldap1.Attributes.Add(new LDAPAttribute("mail"));
Ldap1.Search("uid=" + txtUserID.Text)
string emailaddr = Ldap1.Attributes[0].Value
Title: Email   
Name: Lance
Date: 1/8/2008 9:48:35 AM
Comment:
To get the email, just get the "mail" attribute. With IPWorks v8 (the current version is v8, but note that this older article was initial written with ipworks v6), that would look like this:

Ldap1.DN = "OU=Users,O=Server"
Ldap1.Timeout = 10
Ldap1.Attributes.Clear();
Ldap1.Attributes.Add(new LDAPAttribute("mail"));
Ldap1.Search("uid=" + txtUserID.Text)
string emailaddr = Ldap1.Attributes[0].Value
Title: Retrieve the mailid from Active Directory   
Name: Mohan
Date: 1/8/2008 9:44:30 AM
Comment:
hi,
i want to retrieve the email id of the "user" whose id and password were passed in the DirectoryEntry .
myLDAP = new DirectoryEntry("LDAP://xxxxxxxxxxxxx", user, passwd);
mySearcher = new DirectorySearcher(myLDAP);
mySearcher.Filter = "(objectClass=user)";
mySearcher.SearchScope = SearchScope.OneLevel;
mySearcher.Sort = new SortOption("mail", SortDirection.Ascending);

foreach (SearchResult res in mySearcher.FindAll())
{
DirectoryEntry de = res.GetDirectoryEntry();
Console.WriteLine(de.Properties["mail"].Value);
}
Can you please send me the code or atleast the objectclass and attribute for the mailid .I have tried the Person ,ou,user.etc with the Mail attribute , but could not get.

Please help me .My mail-id is mohan8300@gmail.com
Thank you
Title: LDAP authentication via ASP.NET help.   
Name: Lloyd
Date: 11/20/2007 6:24:49 PM
Comment:
Hi all,
Can anyone help me authentication to a iPlanet LDAP directory via asp.net.

This is my code.
Dim de As DirectoryEntry = New DirectoryEntry("LDAP://" & Host & "/ou=people, ou=staff,o=vu.edu.au", username, password, AuthenticationTypes.ServerBind)

It works fine but i get a Guid{"Exception from HRESULT: 0x8000500D"}

Any help will be appreciated. my email is Lloyd.Thomas@vu.edu.au.

Thanks
Title: ldap authentication for domino server using asp   
Name: ananth
Date: 4/26/2007 2:52:18 AM
Comment:
Hi all,
I need some links or codes for ldap authentication between a domino server and asp
Title: PLain ASP code for IP works ASP   
Name: Deepak
Date: 2/22/2007 6:54:34 AM
Comment:
oops i forgot my email id is deecool@gmail.com
Title: PLain ASP code for IP works ASP   
Name: Deepak
Date: 2/22/2007 6:53:36 AM
Comment:
Hi Lance,
i am trying integration with Domino directory kindly provide me too the plain asp sample code for ipworks asp
Title: LDAP help   
Name: Prasastha
Date: 12/5/2006 12:35:41 AM
Comment:
hi all,

well i have task to integrate LDAP user authentication to an existing website. So could any one help me , which LDAP server to download and configure it. and also code in ASP to connect to LDAP server.
Please send the code to radhika.vadde@gmail.com
Title: LDAP authentication via ASP   
Name: Valerio
Date: 10/20/2006 9:42:25 AM
Comment:
Hi Lance,

Sorry for the time you spent for the same think, but if is not a problem for you I would like to receive the same code sample used for the LDAP IPlanet Server & ASP authentication.
My mail is: valerio.spadaro@st.com

Thanks in advance & best regards,
Valerio
Title: Ldap auth code in asp   
Name: Shashank
Date: 10/10/2006 11:39:41 AM
Comment:
hi Lance,
i have to develop an application of Authenticating Users therough Novell in asp.net can u send me the code
my email address is : sshen4@uis.edu
Title: Classic ASP Example   
Name: Mark Tindall
Date: 9/12/2006 5:55:32 AM
Comment:
Hi,

RE: Performing Web Authentication and Administration with LDAP

Can you send me the CLASSIC ASP example of this please!

info@tindallconsulting.co.uk

Many thanks!!!
Title: LDAP authentication in classic asp   
Name: Jessa
Date: 7/14/2006 5:06:23 AM
Comment:
hello..can i get the code in classic asp.my add is lightjest@yahoo.com.godspeed and many thanks
Title: LDAp and classic ASP   
Name: nalini
Date: 4/28/2006 1:42:51 AM
Comment:
Hi Lance,
the article is very good. I learnt a lot from this. it would be very helpful if you would provide me the code in classic ASP.
my e-mail id is
nalini.devarakonda@gmail.com
Title: LDAP help   
Name: santhosh
Date: 4/5/2006 7:43:12 AM
Comment:
hi all,

well i have task to integrate LDAP user authentication to an existing website. So could any one help me , which LDAP server to download and configure it. and also code in ASP to connect to LDAP server.

Santhosh
Title: ASP / LDAP / iPlanet   
Name: Cedric
Date: 3/23/2006 5:53:37 AM
Comment:
Im interested in authentication users to LDAP IPlanet Server via ASP.

My email address is zhd_1@hotmail.com
Title: Classic ASP Code   
Name: Lance
Date: 10/28/2005 1:58:15 PM
Comment:
I've posted the classic asp code on my personal blog at http://geekswithblogs.net/lance/articles/LdapClassicASP.aspx
Title: Classic ASP Code   
Name: Paul Perry
Date: 10/28/2005 1:00:20 PM
Comment:
Lance,
Would it be possible to post the classic ASP code to do LDAP Authentication? Or would you please sent it to me via e-mail at paul.perry@fedex.com.

Thanks

Paul
Title: .NET LDAP Authentication w/ iPlanet   
Name: Dawn
Date: 10/14/2005 9:08:47 AM
Comment:
Hi Lance, Thank you for the article - big help! I'm using standard .NET to authenticate users via LDAP against an iPlanet directory server. Do you know whether the syntax should be the same as your example? Anything you can offer is appreciated.
Thanks
Dawn - dcwmisc@yahoo.com
Title: AD authentication   
Name: Michael Melby
Date: 7/27/2005 9:57:03 PM
Comment:
If your ASP classic code allows me to authenticate to AD directly I would REALLY like a copy.

michael.melby@leememorial.org

Thank you
Title: LDAP Authentication via ASP   
Name: SY
Date: 7/17/2005 8:45:20 AM
Comment:
Lance,

Can I have a copy of the example in classic asp, thank.

myemail: yew@post.com
Title: classic asp   
Name: mk
Date: 7/4/2005 5:11:44 AM
Comment:
Iwould really like to see how to do this in classic asp. my email is matjaz.kljun at email.si
Title: Re: missing a name space   
Name: Lance
Date: 6/15/2005 9:35:21 AM
Comment:
The only reference required is the nsoftware.ipworks.dll.
Title: missing a name space   
Name: Lhou
Date: 6/15/2005 9:20:29 AM
Comment:
i have download and instal the trial version of the companont .but when i use the above code i get erroe .
i think i am missing a reference
Title: Re: Naghmeh   
Name: Lance Robinson
Date: 6/13/2005 8:46:52 AM
Comment:
In AD, when you call Add you can only add the objectClass attributes (ie, just the first 4 in the sample I gave), not the description, uid, etc. For example:

ldap.AttrCount = 4;
ldap.set_AttrType(0, "objectClass");
ldap.set_AttrValue(0, "top");
ldap.set_AttrType(1, "objectClass");
ldap.set_AttrValue(1, "person");
ldap.set_AttrType(2, "objectClass");
ldap.set_AttrValue(2, "organizationalPerson"); dap.set_AttrType(3,
"objectClass"); ldap.set_AttrValue(3, "inetorgperson");

ldap.Add();
Title: Add method error   
Name: Naghmeh
Date: 6/11/2005 8:26:58 AM
Comment:
hi,
I use the above code for Add method in AD server but I get error. Could you more explain about "Note" in Add partion and give me an example
Title: LDAP and classic ASP   
Name: Jason
Date: 6/7/2005 4:09:53 PM
Comment:
Lance-

Could I get the classic ASP code as well. ualr_jrcole@yahoo.com

Thanks
Title: Re: LDAP Authentication via ASP   
Name: Lance Robinson
Date: 5/13/2005 8:12:48 AM
Comment:
Roland - I sent you the email describing how to do this in classic asp.
Title: LDAP Authentication via ASP   
Name: Roland
Date: 5/13/2005 2:53:14 AM
Comment:
Would you happen to have a code example like the authentication section above using ASP. Im interested in authentication users to LDAP IPlanet Server via ASP. elaim address is rwornor@yahoo.com

Roland
Title: Re: Comments   
Name: Lance Robinson
Date: 5/9/2005 7:10:57 AM
Comment:
Matt: Yes, you can use this with classic ASP as well. Send me an email and I'll send you the classic ASP code, which is very similar.

Rami - the LDAP class is in IP*Works .Net Edition, which you can find at www.nsoftware.com/download/.
Title: declare ldap   
Name: Rami
Date: 5/7/2005 7:00:21 AM
Comment:
Hello
if you Please help me to locate the nsoftware.IPWorks.Ldap()
inorder to try this code..
Title: FeedBack   
Name: Praveenkumar (praveenkumar@gmail.com)
Date: 4/22/2005 3:47:38 AM
Comment:
This article is very useful. I learnt a lot from this article.
Title: Classic ASP?   
Name: Matt
Date: 4/7/2005 7:10:18 PM
Comment:
Is there a way to do LDAP authentication against an external LDAP server (e.g., Sun Directory Server) using classic ASP (pre ASP.Net)?
Title: Re: I can't use this code   
Name: Lance
Date: 4/6/2005 9:36:05 AM
Comment:
Sentil - you have to declare the object.

Either drop the component on the form after installing IP*Works! or manually create a reference to the IP*Works! dll and then create your instance in code:

Dim ldap1 as nsoftware.IPWorks.Ldap = new nsoftware.IPWorks.Ldap()
Title: I cant' use this code   
Name: Senthil
Date: 4/6/2005 5:49:57 AM
Comment:
Hi

I try to use this code but its say some Error like this "Name ldap1 is not declared".

please guide me fast

*** sorry for my English********

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2014 ASPAlliance.com  |  Page Processed at 10/21/2014 2:19:07 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search