Click here to Skip to main content
Click here to Skip to main content

Authentication against Active Directory and Edirectory via LDAP

By , 27 Jan 2004
 

Contents

Figure 1.0 - This is the main window where users login.

Introduction

This article covers HOW-TO authenticate against Microsoft Active Directory and Novell Edirectory via LDAP.

Go to Contents

Background

It is not easy to find an article that talks about how to authenticate users against both MS Active Directory and Novell Edirectory via LDAP. In short, LDAP stands for Lightweight Directory Access Protocol. It is a subset of Directory Access Protocol or DAP. University of Michigan developed it because DAP took up a lot of resources. Anyways, this article goes through all of the necessary steps to start authenticating users against both directory services.

Go to Contents

Functionality Supported

  • Authentication against MS Active Directory
  • Authentication against Novell E-Directory
Go to Contents

Requirements

  • A Server running Active Directory
  • A Server running Edirectory
  • Familiarity with LDAP and how entities are addressed
Go to Contents

Optional Tool

  • Adsvw.exe by Microsoft - This utility allows user to browse LDAP directory. It comes as part of ADSI SDK or as part of support tools in advanced server. It is very helpful when users are trying to find how entities should be referenced. Here is a little tip. If the user was to use it to browse active directory, then make sure Secure Connection is checked. When it comes to Edirectory the check should be on Use Encryp option.
Go to Contents

Using the code

First, add a reference to System.DirectoryServices by going to Project -> Add Reference. When this is done the dialog box as shown by figure 2.0 should display. Under .NET tab click on System.DirectoryServices.dll and click Select. Then click on OK to get back to the project.

Figure 2.0 - This is the dialog where user selects the reference.

In this solution, there is a class namely Authenticate. It is contained inside the file called Authenticate.cs. You should add it to your project or copy and paste the class from The Code section. Create a new instance of Authenticate and assign it to aAuthent. Several values needed to be initialized before doing the actual login.

Authenticate aAuthent = new Authenticate();

I'll be referring to various widgets from this point. There are 3 text edit and 2 radio button widgets you need to worry about. Please map the direction appropriately in your workspace. Set the Domain name to the value held by txtDomain widget by invoking SetDomain. This is where user entered IP address (i.e. 10.x.x.x) or host name (i.e. mydomain.com) of the target server. Note, that all but one Set/Modifier methods in this class returns boolean. It just indicates whether it modified the variable successfully or not. This may be against the convention, but, checking the argument inside the function was much more favorable to me instead of duplicating the effort elsewhere.

if (!(aAuthent.SetDomain(this.txtDomain.Text)))
{
    // error message here
}

Then, invoke SetUser function to take in the value of text widget txtUser. This is where user name is supplied.

if (!(aAuthent.SetUser(this.txtUser.Text)))
{
    // error message here
}


After that, call SetPass function to pass the value of txtPassword. This is where user password is supplied.

if (!(aAuthent.SetPass(this.txtPassword.Text)))
{
    // error message here
}


Next, check which directory this user desires to authenticate against. In this solution, there are two radio buttons namely rbtnED and rbtnAD. If the former is checked then invoke SetAuthenticationType with the argument set to true. This will tell the Authenticate class to use Secure Socket Layer or SSL. Edirectory uses ssl protocol to perform authentication task. In the latter case, the boolean value false would instruct the class to use Secure. Active Directory utilizes the secure method. The internal of those communication protocols or methods are outside the scope of this article. Therefore, I will skip them.

if (this.rbtnED.Checked)
  aAuthent.SetAuthenticationType(true);r>
else if (this.rbtnAD.Checked)
  aAuthent.SetAuthenticationType(false);

Finally, the Login function inside this class should be invoked. It handles everything from this point. On success, it will welcome the user; other wise display failure message.

aAuthent.Login(); 
Go to Contents

The Code

 
  /// <summary>
  /// This class performs user authentication against Active Directory and
  /// Novell Edirectory.
  /// </summary>
  public class Authenticate
  {
    /// <summary>
    /// string specifying user name
    /// </summary>
    private string strUser;
      
    /// <summary>
    /// string specifying user password
    /// </summary>
    private string strPass;
      
    /// <summary>
    /// string specifying user domain
    /// </summary>
    private string strDomain;      
    
    /// <summary>
    /// AuthenticationTypes specifying the security 
    /// protocol to use, i.e. Secure, SSL
    /// </summary>
    private AuthenticationTypes atAuthentType;
      
    /// <summary>
    /// default constructor
    /// </summary>
    public Authenticate()
    {
    }
        
    /// <summary>
    /// function that sets the domain name
    /// </summary>
    /// <param name="strValue"></param>
    /// <returns>It returns true, if user passed 
    ///            something; otherwise, false </returns>
    public bool SetDomain(string strValue)
    {
      if (strValue.Length <= 0)
        return false;
        
      this.strDomain = "LDAP://" + strValue;
      return true;
    }
     
    /// <summary>
    /// function that sets user name
    /// </summary>
    /// <param name="strValue"></param>
    /// <returns>It returns true, if user passed 
    ///          something; otherwise, false </returns>
    public bool SetUser(string strValue)
    {
      if (strValue.Length <= 0)
        return false;
        
      this.strUser = strValue;
      return true;
    }
    
    /// <summary>
    /// function that sets user password
    /// </summary>
    /// <param name="strValue"></param>
    /// <returns>It returns true, if user passed 
    ///          something; otherwise, false </returns>
    public bool SetPass(string strValue)
    {
      if (strValue.Length <= 0)
        return false;
        
      this.strPass = strValue;
      return true;
    }
    
    /// <summary>
    /// function that sets user authentication type
    /// </summary>
    /// <param name="bValue"></param>
    public void SetAuthenticationType(bool bValue)
    {
      // set ssl to true if true is found
      if (bValue)
        atAuthentType = AuthenticationTypes.SecureSocketsLayer;
      // otherwise set it to secure  
      else
        atAuthentType = AuthenticationTypes.Secure;
    }
    
    /// <summary>
    /// function that performs login task
    /// and welcomes user if they are verified
    /// </summary>
    public void Login()
    {      
      // now create the directory entry to establish connection
      using(DirectoryEntry deDirEntry = new DirectoryEntry(this.strDomain, 
                                                           this.strUser, 
                                                           this.strPass,
                                                           this.atAuthentType)) 

      {
        // if user is verified then it will welcome them 
        try
        {                 
          MessageBox.Show("Welcome to '" + deDirEntry.Name + "'");
          
          // TODO: add your specific tasks here
        }
        catch (Exception exp)
        {
          MessageBox.Show("Sorry, unable to verify your information");
        }
      }
    
    }
  }

Go to Contents

Points of Interest

One thing that was problematic was the way addressing worked. In Active Directory, users are allowed to pass in their name without utilizing the distinguished name format. If they were to try the same trick against Edirectory then it would fail right away.

Go to Contents

HOW-TO use this Demo

Authenticating against Edirectory

First, enter the user name. This is something the user needs to find out before proceeding with the next step. Use the ADSVW utility that was recommended to find out how the current user should be addressed. In this example, cn=userA,ou=rajibOU,o=rajibContext means there is an individual named userA belonging to organization unit rajibOU attempting to log in to the resources under rajibContext.

Figure 3.0 - User enters the distinguished name.

Second, enter the password for this particular user.

Figure 3.1 - User enters the password.

Third, enter the domain name or IP address that is applicable.

Figure 3.2 - User enters the IP address of the target server.

Fourth, choose either Active Directory or Edirectory.

Figure 3.2 - User selects the directory service.

Finally, click Login and it should produce the output as shown in figure 3.4.

Figure 3.4 - Show the outcome of user login attempt.

Authenticating against Active Directory

First, enter the user name.

Figure 3.5 - User enters the distinguished name.

Second, enter the password for this particular user.

Figure 3.6 - User enters the password.

Third, enter the domain name or IP address that is applicable.

Figure 3.7 - User enters the IP address of the target server.

Fourth, choose Active Directory.

Figure 3.8 - User selects the directory service.

Finally, click Login and it should produce the output as shown in figure 3.9.

Figure 3.9 - Shows the outcome of user login attempt.

Go to Contents

Conclusion

Well, this is my second article. I hope you found it useful and intuitive enough.

Go to Contents

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Rajib Bahar
Database Developer
United States United States
Member
My personal/quasi-work blog:
http://www.rajib-bahar.com
http://www.icdotnet.com
http://www.icsql.com
 
YouTube Vlogs:
http://www.youtube.com/icsql - sql tutorials in video
http://www.youtube.com/rajib2k5 - my random vlog on art and other stuff outside of the geek world... Smile | :)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5member@amitgajjar11 Sep '12 - 3:23 
great job. it could be better. 5
Generalc++ versionmembersergeyltd8 Feb '10 - 4:31 
I'm very interested in the c++ version.
 
I would be very grateful if someone shared с++ code implementation.
 
Thanks you,
my email: sergeyltd@gmail.com
Sergey
GeneralGreat article!memberidrivefastlane1 Dec '09 - 23:09 
Easy to follow, easy to understand! Thanks!
GeneralYet another AD validator classmemberpr_programmer30 Jun '09 - 5:22 
See if anyone finds use for it. Thnx.
 
http://praveen-rangarajan.blogspot.com/2009/06/c-class-to-validate-user-credentials-on.html
GeneralIt works only if CN=sAMAccountNamememberleto5824 Jun '09 - 1:45 
Hi,
 
I tried with both this .Net program and with C++ ADsOpenObject(), I get exactly the same (both are probably using the same lib):
If you enter sAMAccountName as "User" or "CN=<sAMAccountName>[,...]" (in this case, only CN matters, I can write whatever back the following comma...) it works.
But if you enter the real DN, with the real CN (for me: <forname lastname> ) instead of sAMAccountName (for me: <initials> ), it will not work (wrong credentials), even if DN as user name is supposed to work.
 
It is a problem for me, since my app can only get DN (but not sAMAccountName) for a user with a restricted access account, then try to log to this DN with the password the user provided.
 
Do you know any library (other than ADSI.dll) that works as expected ?
 
Ragards,
Leto
GeneralMy vote of 1membercarlos.muentes24 Dec '08 - 5:50 
Poor code quality, follows hungarian notation for variable names which is against C# best practices
GeneralContact me via my blog http://www.rajib-bahar.commemberRajib Bahar30 Nov '08 - 14:05 
I do not have much time to check this article constantly. If you need to reach out then please touch base with me via my blog at http://www.rajib-bahar.com.
 
thanks
QuestionLDAP Authentication issuemembersrviswa200018 Nov '07 - 23:58 
Hi,
 
Please help me If any one has solved the problem. Iam trying to authenticate an user in eDirectory using c# (DirectoryEntry). Its giving me an error "The Requested authentication method is not supported by the server". I have give the below parameters correctly.
 
1. Domain
2. CN connection string
3. User name
4. Password.
 
I have given the authentication type as "Secured". It throws me this error. using Any other authentication type produces the error "Invalid Dn syntax has been specififed". However, with the above parameters its working fine (able to connect and reteive user details) if its authenticated against admin user & passowrd. I need to authenticate against specific user & password.
 
Can someone please let me know which authentication type to be used for authentication against eDirectory? and what configurations to be checked
if Secured authentication is used.
 
Many Thanks
 
Viswa

 
Viswanath
GeneralC++ versionmemberJuanCR29 Aug '07 - 12:35 
I'm very interested in the c++ version.
 
Thanks you,
my email: jlsanchez@gmx.net
Juan
GeneralWeb login against Active directory!memberJohn Ahmad4 Aug '06 - 23:17 
Thank you sharing your knowledge Smile | :) I really appreciate the way you are
spreading knowledge. I have a question since I am newer to .Net ; How can
login with web form ? I got some concept from authenticate.cs but authenticateForm ... Like if I am using web form I can I get authenticated.
please provide me sufficent information so that i will be able to perform
 

 

GeneralC++ versionmemberNunzioCar10 Apr '06 - 0:55 
Great!!!!
 
Could I also have the C++ version of it.
 
my email : cnun@inwind.it
Thanks a lot.
 
Nunzio
GeneralC++ versionmembernamtt24 Feb '06 - 6:48 
I'm very interested in the c++ version.
 
Thanks in advance
my email: namtt@khai-tri.com
namtiu
 

Generalproblem to authenticate against Novell via SSLmemberknittel1 Feb '06 - 5:11 
Hi,
 
i try to authenticate an Edirectory with SSL but it don't work.
The Novell Certificate was imported to the certmgr.exe from .NET SDK (was it the right store?)
The Novell Server is Version 51.
 
Thanks for help!
 
Peter
GeneralRe: problem to authenticate against Novell via SSLmemberrolias10115 Oct '06 - 3:33 
Did you ever get this to work? I am having the same problem. Any help you can give me would be very appreciated.
Thanks,
Sean Babcock
scbabcock@ccisd.us

Generalexample from microsoftmemberstjanus3 Nov '05 - 10:43 
there's an example from microsoft at msdn http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT02.asp
 
read chapter 3 "Develop LDAP Authentication Code to Look Up the User in Active Directory".
GeneralDirectorySearcher.FindAll() method ErrorsussSandesh Kulkarni25 Aug '05 - 21:36 
Hello,
I m sandesh
working on LDAP devlopment in .net c# i m using DirectoryServices namespace
I m able to connect ot Active directory.
but not on an Ldap server. why ?
when i bind it gets connected but directory searcher object gives me error
"Object not found on server" pls help me....
here is sample code which i m using
 
public bool Authenticate(string uid, string password)
{
bool authenticated = false;
 
//we want to bind anonymously first
DirectoryEntry root =
new DirectoryEntry(
ldapPath,// //;
 
uid,
password,
AuthenticationTypes.None
);
 
using (root)
{
string StrFilter = "(&(objectclass=group)(mail=Email address))";
//DirectorySearcher ds = new DirectorySearcher(root,StrFilter);
DirectorySearcher ds =new DirectorySearcher(root,StrFilter,new string[]{"mail","cn"},SearchScope.Subtree);
SearchResult sr = null;
//we need to find this UID that we got
using (SearchResultCollection src = ds.FindAll()) // here i m getting error "Object not found
{
if (src.Count > 0) { sr = src[1];}
}
 

thanks in advance

GeneralRe: DirectorySearcher.FindAll() method ErrormemberDave Bacher28 Mar '06 - 11:18 
Make sure that your LDAP path looks like this:
LDAP://server[:port]
 
For example:
LDAP://192.168.0.1:10000
-or-
LDAP://ldap.mydomain.com
-or-
LDAP://ldap.mydomain.com:10000
 
The "LDAP://" URI tells the Microsoft API to use LDAP instead of active directory. Alternatively, do a search for NIU.WebTeam.Utilities.LDAP.dll in Google -- that assembly provides a much easier interface for LDAP scenarios.
GeneralNeed some help with LDAPmemberNalin Bakshi2 Aug '05 - 18:36 
Hi Man!
Nice work. I found your article interesting but was unable to deploy it. I don't understand how I can deploy LDAP to work with my active directory. I am just too confused. I want to know how i can connect all this (Active Directory, LDAP and java) to start and make an authentication program for my application. I will be very thankful to u. My e-mail id is nalin_bakshi@yahoo.com
 
Regards,
Nalin Bakshi.
Generalneed java codesussrahul_s999930 Jun '05 - 11:09 
can you please email me at rshah02@syr.edu the java code to authenticate using active directory
 
thanks
rahul
GeneralRe: need java codesussAnonymous30 Jun '05 - 11:57 
Please see http://www.codeproject.com/csharp/arbauthentication.asp?select=1090431&df=100&forumid=32468#xx1090431xx[^]
Generalc++ versionmembernoonan713 Jun '05 - 22:11 
I'm very interested in the c++ version.
 
Thanks in advance.
 
noonan7@gmail.com
 
Noonan
GeneralRe: c++ versionsussAnonymous14 Jun '05 - 6:44 
Please see http://www.codeproject.com/csharp/arbauthentication.asp?select=1090431&df=100&forumid=32468#xx1090431xx[^]
GeneralLocking out account after retriesmemberNinju Bohra16 May '05 - 7:33 
Hello,
 
Good example of the System.DirectoryServices API. I was wondering if there is any API call that would handle the locking out of the account if I pass in a incorrect password too many times.
 
I would like building a system around the API you demonstrated but don't want somebody repeatedly guessing the passwords?
 
Any ideas,
 
ThanxCool | :cool:
GeneralRe: Locking out account after retriesmemberstjanus3 Nov '05 - 11:21 
hello,
 
imho this will be done automatically.
if you try to authenticate with a wrong password the badPwdCount-Property of the user will be increased. if it reaches the maximum value defined for the domain the user will be locked out automatically for a specified time.
 
the badPwdCount-Property is explained at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ad/ad/security_properties.asp
QuestionHow is this Useful?sussAnonymous10 May '05 - 2:00 
How is this useful when the user needs to know their distinguished name? The majority of users will not know this information(it would be meaningless to them). If you try and use a regular username password scheme you still get a success message even though the user is not authenticated. In fact you can put in any information for username and password and it will work so long as the root ldap domain is correct.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 28 Jan 2004
Article Copyright 2004 by Rajib Bahar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid