ASP.NET 2.0 Changing Active Directory User’s Password

I have a project, to create a web interface to let user login to and change their Active Directory(AD) password. Never been touching the AD for my life, this being the great explore for me to deal with AD object in .NET framework.

To be able to access to AD, we will need to include a reference to our project, to include a System.DirecotryServices dll into our web project. In order to use the DirectoryEntry class, an imports statement will be needed, as following,

[cc lang=”vbnet” escaped=”true”]Imports System.DirectoryServices[/cc]

To keep things simple, as I promised myself before I start the project, giving a visit to MSDN, I learnt that the LDAP path to the AD is something like this: LDAP://litwareinc/CN=Users,DC=litwareinc,DC=com , the litwareinc will be the domain name and the DC=com will the the .com thing (yes, I guess it).  From the Internet, I learn a method to be call to change the password will be ChangePasswordand SetPassword. The SetPassword is the method that act as administrator, which does not need to specify a old password, so the suitable method for my case will be the ChangePassword.

First to create a DirectoryEntry object, I will need to provide the path to our AD, which is theLDAP://litwareinc/CN=Users,DC=litwareinc,DC=com , after that we need to invoke the ChangePassword method from the DirectoryEntry object, it will looks something like this:


[cc lang=”vbnet” escaped=”true”]
Dim deObj As New DirectoryEntry(“LDAP://litwareinc/CN=Users , DC=litwareinc , DC=com”, UserName , Password , AuthenticationTypes.Secure)
deObj.Invoke(“ChangePassword”, New Object(){OldPassword, NewPassword})[/cc]

First run, the above codes threw me an exception Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME)). after doing some trial and error, realized that I need to specified the user’s display name at the path, e.g. I want to change the name for user Amy Alberts, which using AmyA as login name, and my AD path should beLDAP://litwareinc/CN=Amy Alberts,CN=Users,DC=litwareinc,DC=com.

The question came, people won’t input their full name when they login, how do I retrieve the full name based on the login ID? From Object Viewer, I found something useful, DirecotrySearcher, which allow me to set filter on the DirectoryEntry object created previously. OK, solved first problem, yet another came, what is the filter string looks like? Another wild guess (no harm from guessing), it will search by the properties, or maybe part of the key in the path. To find out list of the properties available, I will need to cycle through the DirectoryEntry’s child and print it out (day 2 of the project, which is the state I start coding, I don’t have Internet access, have to do it the hard way :S).

In order to retrieve the list of the properties, I’m doing the hard and stupid way, hard coded login for the user first (I do have a test platform):
[cc lang=”vbnet” escaped=”true”]
Dim dePath As String = “LDAP://litwareinc/CN=Amy Alberts,CN=Users,DC=litwareinc,DC=com”
Dim objDE As New DirectoryEntry(dePath,”amya”, “P@ssw0rd000″, AuthenticationTypes.Secure)

For Each de As PropertyValueCollection In objDE.Properties
Response.Write(de.PropertyName & ” : ” & de.Value.ToString & “”)
Next[/cc]

By studying the list printed, I learn that the properties that match with the login ID will be sAMAccountName. So now I can use the DirectorySearcher to filter out those account to only to AmyA user account, by matching the sAMAccountName to AmyA (which user use to login). After search, I can retrieve the Name from the user account, which will be Amy Alberts, now I can merge my search result Name to my path, final codes will looks like this:
[cc lang=”vbnet” escaped=”true”]
Imports System.DirectoryServices

Partial Class _Default Inherits System.Web.UI.Page
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
Dim domainName As String = ConfigurationManager.AppSettings(“DOMAIN”).ToString
Dim dcName As String = ConfigurationManager.AppSettings(“DC”).ToString
Dim dePath As String = “LDAP://” & domainName & “/CN=Users,DC=” & domainName & “,DC=” & dcName

Try
Dim deSearch As New DirectorySearcher(New DirectoryEntry(dePath))
Dim result As SearchResult
Dim dePathChange As String
Dim deObj As DirectoryEntry

deSearch.Filter = “sAMAccountName=” & Trim(txtUsername.Text)
result = deSearch.FindOne()
dePathChange = “LDAP://” & domainName & “/CN=” & result.Properties(“Name”).Item(0) & “,CN=Users,DC=” & domainName & “,DC=” & dcName
deObj = New DirectoryEntry(dePathChange, Trim(txtUsername.Text), txtPassword.Text, AuthenticationTypes.Secure)
deObj.Invoke(“ChangePassword”,New Object() {txtPassword.Text, txtConfirmPassword.Text})
deObj.CommitChanges()

Dim jsString As String = “alert(‘Password Successfully Changed!’);location.replace(‘Default.aspx’);”

Page.ClientScript.RegisterClientScriptBlock(Me.GetType,”Successful”, jsString)
Catch ex As DirectoryServicesCOMException
lblError.Text = ex.Message
End Try
End Sub
End Class[/cc]
Without having to hardcode the domain name, moving all settings to Web.config.

Finally it works!

 

One thought on “ASP.NET 2.0 Changing Active Directory User’s Password

  1. Stephan..you would not have to write exta code for User Display name when you are Re-defining the Path..Simple make it like this it will work fine.
    I mean instead of this line :
    dePathChange = “LDAP://” & domainName & “/CN=” & result.Properties(“Name”).Item(0) & “,CN=Users,DC=” & domainName & “,DC=” & dcName

    USE THIS:
    dePathChange = deSearch.path;

Leave a Reply

Your email address will not be published. Required fields are marked *