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