Tuesday, December 1, 2009

Active Directory Using VB.NET

This article discusses working within the Active Directory (AD) using VB.NET, how to query the AD, How to authenticate the user, how to retrieve the user details using Domain User ID, how to retrieve the user details using domain e-mail id etc

The Active Directory is the Windows directory service that provides a unified view of the entire network. Working with the Active Directory is a lot like working with a database, you write queries based on the information you want to retrieve.

Recently, at work, I was tasked with creating a single signon for the application I am currently programming to allow the user to use the application without entering the userid and password details; Also I had to ensure that in the event the application was ever taken off-site, that it couldn't run; This would prevent an individual from taking the application off-site and attempting to use it.

Then I thought of using the Active Directory of the company network to achieve the Single Signon as well as Security.

Active directory seemed to be the most secure way as only a select group of people actually have the permissions to alter the Active Directory in any way.

I built the logic using the System.DirectoryServices namespace.

System.DirectoryServices: The System.DirectoryServices namespace built into the .NET Framework is designed to provide programming access to LDAP directories (Active Directory).

To start querying Active Directory from your VB.NET code, you simply add a reference to the System.DirectoryServices.dll in your project and the following Imports statement to your code:


Imports
System.DirectoryServices

When the application is launched, it will check the name the user was logged in as:

Environment.UserName.ToString. It will return the user name in the format: DOMAIN\USERNAME

After getting the user name the application will query the Active Directory to ensure this is a valid network account and they have permissions to be using this application.

The first thing to do when working with the Active Directory is to create a connection to the Active Directory:

dirEntry = New System.DirectoryServices.DirectoryEntry("LDAP://" & DOMAIN_NAME)

You can replace the path with the one specific to your network.

The next thing to search for the provided user to ensure that the login provided is a valid one.

dirSearcher = New

System.DirectoryServices.DirectorySearcher(dirEntry)

dirSearcher.Filter = "(samAccountName=" & m_LoginName & ")"

Dim sr As SearchResult = dirSearcher.FindOne()

If sr Is Nothing Then 'return false if user isn't found
lblStatus.Text = "User authentication failed"
Return False
End If

The condition used here to Search for an entry for the logged in user. The "samAccountName" is the name of the field used to store Domain User ID.

If the user does not exist in the Active Directory, the result will be nothing.

The .FindOne() method will be used to stop searching as soon as the match is found.

 

Sample Code 1:

The IsLogonValid is used to validate the logged in user. It will search for the provided user in the Active Directory. The function will return true or false depending if the login provided is a valid one. With this function, if the selected user is found, and then True is returned, else False is returned, letting the programmer know that this isn't a valid user in the Active Directory.

Private m_ServerName As String
Private m_LoginName As String

Private m_Authenicate As String

Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent() 

' Add any initialization after the InitializeComponent() call.
m_ServerName = DOMAIN_NAME ' Your Domain Name
m_LoginName = Environment.UserName.ToString
m_Authenicate = My.User.Name 
End Sub 
 

Public Function IsLogonValid() As Boolean

Dim m_LoginName As String
Dim dirEntry As System.DirectoryServices.DirectoryEntry

Dim dirSearcher As System.DirectoryServices.DirectorySearcher

lblStatus.Text = "Validating User Account" 

Try 
m_LoginName = Environment.UserName.ToString 'The logged in user ID
dirEntry = New System.DirectoryServices.DirectoryEntry("LDAP://" & DOMAIN_NAME) 
dirSearcher = New System.DirectoryServices.DirectorySearcher(dirEntry) 
dirSearcher.Filter = "(samAccountName=" & m_LoginName & ")"

       'Use the .FindOne() Method to stop as soon as a match is found

Dim sr As SearchResult = dirSearcher.FindOne() 

If sr Is Nothing Then 'return false if user isn't found
lblStatus.Text = "User authentication failed"
Return False
End If

Dim de As System.DirectoryServices.DirectoryEntry = sr.GetDirectoryEntry()

sUserName = de.Properties("GivenName").Value.ToString()
 

lblStatus.Text = "User authentication success"


Return True  'Valid user


Catch ex As Exception ' return false if exception occurs

lblStatus.Text = "User authentication failed"


Return False


End Try


End Function


 

Sample Code 2:

The DisplayActiveDirUserDetails function is used to retrieve the FirstName, Last Name and e-mail adddress of the logged in user.

The PropertiesToLoad property of the DirectorySearcher object is a collection containing attribute names of AD objects that we want the query to return. By analogy with SQL query, the Filter property serves as the WHERE clause and the PropertiesToLoad property works as a list of column names that the query will return.

To retrieve specific properties, we need add them to the Collection before we begin the search. For example, searcher.ProperiesToLoad("GivenName") will add the GivenName property to the list of properties to retrieve in the search.

Some of the directory entry properties are

  • SAMAccountName – Users Login Name
  • Mail –E-Mail
  • Sn – SurName or Last Name
  • GivenName – First Name
  • Title – User Title
  • Phone – User telephone number
  • Department – User's Department etc.
  • Mobile – Mobile Phone number
  • City – User's City


 

In this example I have retrieved only FirstName, LastName and e-mail address.


 

Basically, this is a good practice to limit the amount of returning properties as much as you can. It can reduce execution time of the query significantly.


 

Private Function DisplayActiveDirUserDetails(ByVal USERID As
String) As Boolean


Dim dirEntry As System.DirectoryServices.DirectoryEntry


Dim dirSearcher As System.DirectoryServices.DirectorySearcher

lblStatus.Text = "Validating User Account"

Try dirEntry = New System.DirectoryServices.DirectoryEntry("LDAP://" & DOMAIN_NAME)

dirSearcher = New System.DirectoryServices.DirectorySearcher(dirEntry) 

 dirSearcher.Filter = "(samAccountName=" & USERID & ")"

        'The PropertiesToLoad.Add method will be useful when retrieving only the selected properties.

'In this example I have retrieved only GivenName, Mail and sn

'There are many other properties are available


dirSearcher.PropertiesToLoad.Add("GivenName")
'Users First Name
dirSearcher.PropertiesToLoad.Add("Mail")
'Users e-mail address
dirSearcher.PropertiesToLoad.Add("sn")
'Users last name

Dim sr As SearchResult = dirSearcher.FindOne()

If sr Is Nothing Then 'return false if user isn't found
lblStatus.Text = "Invalid UserID"
Return False
End If

'Retrieve the user's First Name, e-mail and Last Name and assigns them to text boxes

Dim de As System.DirectoryServices.DirectoryEntry = sr.GetDirectoryEntry() 

If Not de.Properties("GivenName").Value Is Nothing Then
txtUserName.Text = de.Properties("GivenName").Value.ToString()
End If 

If Not de.Properties("Mail").Value Is Nothing Then
txtEmail.Text = de.Properties("Mail").Value.ToString()
End If

If Not de.Properties("LastName").Value Is Nothing Then
txtLastName.Text = de.Properties("LastName").Value.ToString()
End If

Return True
'Valid user

Catch e As Exception ' return false if exception occurs

MsgBox("User Authetication Exception: " & e.Message)

Return False

End Try

End Function 
 

Sample Code 3:

The GetUserPropsUsingEmail function is used to retrieve the domain user Id using domain e-mail address.

The userPrincipalName property of Active directory determines the Domain e-mail address of the User.
 

Public Function GetUserPropsUsingEmail() As String


Dim strFullName As String = ""

Dim sPath As String = ""

Dim objDirEnt As New DirectoryEntry("LDAP://" & DOMAIN_NAME)

Dim objSearcher As New DirectorySearcher(objDirEnt)
Dim objSearchRes As SearchResult

' Filter by Lotus Notes internet name

objSearcher.Filter = "(userPrincipalName=" & txtInternetName.Text & ")"


Try
' count should be 1

If objSearcher.FindAll.Count > 0 Then

For Each objSearchRes In objSearcher.FindAll
sPath = objSearchRes.GetDirectoryEntry.Path

Next
objDirEnt.Close()

objDirEnt.Path = sPath


'get domain short name

strFullName = objDirEnt.Invoke("GET", "samAccountName")


End If


Catch ' return nothing if user isn't found

strFullName = ""


End Try


Return strFullName


End Function


 

14 comments:

  1. thanks a lot my dear friends

    ReplyDelete
  2. This is a good logger:
    http://www.kellermansoftware.com/p-14-net-logging-library.aspx

    ReplyDelete
  3. Using the System.DirectoryServices namespace in the .NET Framework, you can also create a list of all the computers listed in the Active Directory.

    ReplyDelete
  4. Does this work with Visual Studio 2013?

    ReplyDelete
  5. Anonymous Says:

    March 11, 2014 at 1:17 PM


    Does this work with Visual Studio 2013?

    WHY WOULD YOU NOT TEST IT? DO YOU WANT EVERYTHING READY FOR YOU? YOU NEVER LEARN LIKE THIS

    ReplyDelete
  6. Thanks!
    Using Visual Studio 2013 express... Been searching a lot, but this was the first description of these functions which actually worked when tried,

    ReplyDelete
  7. I want code that will authenticate with ad using vb.net and login into vb application

    ReplyDelete
  8. I want code that will authenticate with ad using vb.net and login into vb application

    ReplyDelete
  9. I want code that will authenticate with ad using vb.net and login into vb application

    ReplyDelete
  10. The main motive of the Hadoop big data solution is to spread the knowledge so that they can give more big data engineers to the world.

    ReplyDelete
  11. I am happy to find your distinguished way of writing the post. Now you make it easy for me to understand and implement the concept. Thank you for the post. read

    ReplyDelete
  12. I just read your blog. It is really impressive and informative. The way you expressed all thoughts is mind blowing. Good Job! 5 Best-Reviewed VB.Net Development Companies which help you best solution for your business.

    ReplyDelete