Back in October of 2009 I created a WPF login screen (Figure 1) that just showed how to create the layout for a login screen. That one sample is probably the most downloaded sample we have. So in this blog post, I thought I would update that screen and also hook it up to show how to authenticate your user against Active Directory.
Figure 1: Original WPF Login Screen
I have updated not only the code behind for this login screen, but also the look and feel as shown in Figure 2.
Figure 2: An Updated WPF Login Screen
The UI
To create the UI for this login screen you can refer to my October of 2009 blog post to see how to create the borderless window. You can then look at the sample code to see how I created the linear gradient brush for the background. There are just a few differences in this screen compared to the old version. First, I changed the key image and instead of using words for the Cancel and Login buttons, I used some icons. Secondly I added a text box to hold the Domain name that you wish to authenticate against. This text box is automatically filled in if you are connected to a network. In the Window_Loaded event procedure of the winLogin window you can retrieve the user’s domain name from the Environment.UserDomainName property. For example:
txtDomain.Text = Environment.UserDomainName
The ADHelper Class
Instead of coding the call to authenticate the user directly in the login screen I created an ADHelper class. This will make it easier if you want to add additional AD calls in the future. The ADHelper class contains just one method at this time called AuthenticateUser. This method authenticates a user name and password against the specified domain. The login screen will gather the credentials from the user such as their user name and password, and also the domain name to authenticate against. To use this ADHelper class you will need to add a reference to the System.DirectoryServices.dll in .NET.
The AuthenticateUser Method
In order to authenticate a user against your Active Directory you will need to supply a valid LDAP path string to the constructor of the DirectoryEntry class. The LDAP path string will be in the format LDAP://DomainName. You will also pass in the user name and password to the constructor of the DirectoryEntry class as well. With a DirectoryEntry object populated with this LDAP path string, the user name and password you will now pass this object to the constructor of a DirectorySearcher object. You then perform the FindOne method on the DirectorySearcher object. If the DirectorySearcher object returns a SearchResult then the credentials supplied are valid. If the credentials are not valid on the Active Directory then an exception is thrown.
C#public bool AuthenticateUser(string domainName, string userName, string password){ bool ret = false;
try { DirectoryEntry de = new DirectoryEntry("LDAP://" + domainName, userName, password); DirectorySearcher dsearch = new DirectorySearcher(de); SearchResult results = null;
results = dsearch.FindOne();
ret = true; } catch { ret = false; }
return ret;}
Visual Basic
Public Function AuthenticateUser(ByVal domainName As String, _ ByVal userName As String, ByVal password As String) As Boolean Dim ret As Boolean = False
Try Dim de As New DirectoryEntry("LDAP://" & domainName, _ userName, password) Dim dsearch As New DirectorySearcher(de) Dim results As SearchResult = Nothing
results = dsearch.FindOne()
ret = True Catch ret = False End Try
Return retEnd Function
In the Click event procedure under the Login button you will find the following code that will validate the credentials that the user types into the login window.
C#private void btnLogin_Click(object sender, RoutedEventArgs e){ ADHelper ad = new ADHelper();
if(ad.AuthenticateUser(txtDomain.Text, txtUserName.Text, txtPassword.Password)) DialogResult = true; else MessageBox.Show("Unable to Authenticate Using the Supplied Credentials");}
Visual BasicPrivate Sub btnLogin_Click(ByVal sender As Object, _ ByVal e As RoutedEventArgs) Dim ad As New ADHelper()
If ad.AuthenticateUser(txtDomain.Text, txtUserName.Text, _ txtPassword.Password) Then DialogResult = True Else MessageBox.Show("Unable to Authenticate Using the Supplied Credentials") End IfEnd Sub
Displaying the Login Screen
At some point when your application launches, you will need to display your login screen modally. Below is the code that you would call to display the login form (named winLogin in my sample application). This code is called from the main application form, and thus the owner of the login screen is set to “this”. You then call the ShowDialog method on the login screen to have this form displayed modally. After the user clicks on one of the two buttons you need to check to see what the DialogResult property was set to. The DialogResult property is a nullable type and thus you first need to check to see if the value has been set.
C#
private void DisplayLoginScreen(){ winLogin win = new winLogin();
win.Owner = this; win.ShowDialog(); if (win.DialogResult.HasValue && win.DialogResult.Value) MessageBox.Show("User Logged In"); else this.Close();}
Visual Basic
Private Sub DisplayLoginScreen() Dim win As New winLogin()
win.Owner = Me win.ShowDialog() If win.DialogResult.HasValue And win.DialogResult.Value Then MessageBox.Show("User Logged In") Else Me.Close() End IfEnd Sub
Summary
Creating a nice looking login screen is fairly simple to do in WPF. Using the Active Directory services from a WPF application should make your desktop programming task easier as you do not need to create your own user authentication system. I hope this article gave you some ideas on how to create a login screen in WPF.
NOTE: You can download the complete sample code for this blog entry at my website: http://www.pdsa.com/downloads. Click on Tips & Tricks, then select 'WPF Login Verification Using Active Directory' from the drop down list.
Good Luck with your Coding,Paul Sheriff
** SPECIAL OFFER FOR MY BLOG READERS **We frequently offer a FREE gift for readers of my blog. Visit http://www.pdsa.com/Event/Blog for your FREE gift!