Password Lockout Option: Active Directory Membership Provider

In continuation on Password Options with the ASP.NET 2.0 Membership Provider--using Active Directory Application Mode—this blog will discuss how to enable the password lockout option.

 

When using the SQLMembershipProvider the schema to track “failed password attempts”, “failed attempts” to answer the password question and the “time window” between each failed attempt is already created for us by default.  However, with the ActiveDirectoryMembershipProvider--with either ActiveDirectory or ADAM--there is no default schemas to capture failed password attempts within a certain time window. 

 

There are, thus, a few steps that need to be followed to successfully enable password lockout:

  • Create three new schemas attributes to the Active Directory or ADAM directory.
  • Modify your application Web config file to map to the schema modifications
  • Enable password lockout in the local Account Policy.

Schema modifications:

Creating the Failed Password Count, Failed Password Answer Time and Failed Password Locked Out Time attributes--as defined below--is not difficult in the ADAM ADSI Edit tool under the Schema configuration, but initially it takes a while to figure out what values are required by the attribute schema wizard.  Below is an example of the values that you can use in your Active Directory or ADAM directory.

 

cn: FailedPwdCount

OMSyntax: 2 (for type integer)

lDAPDisplayName: FailedPwdCount

isSingleValued: TRUE

AttributeSyntax: 2.5.5.9 (Active Directory syntax type of Unicode)

AttributeID: 1.2.840.113556.1.6.1.1.6223 (Unique Object Identifiers (OIDs))

cn: FailedPwdAnswerTime

OMSyntax: 65 (for Large integer/Interval)

lDAPDisplayName: FailedPwdAnswerTime

isSingleValued: TRUE

AttributeSyntax: 2.5.5.16

AttributeID: 1.2.840.113556.1.6.1.1.6224

cn: FailedPwdLockOutTime

OMSyntax: 65 (for Large integer/Interval)

lDAPDisplayName: FailedPwdLockOutTime

isSingleValued: TRUE

AttributeSyntax: 2.5.5.16

AttributeID: 1.2.840.113556.1.6.1.1.6225

 

For definition on the Attributes value the following URLs provide a good reference:

OMSyntax:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ad/ad/choosing_a_syntax.asp

AttributeSyntax:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/mapping_active_directory_syntax_to_adsi_syntax.asp

AttibuteID:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ad/ad/object_identifiers.asp

 

Modify Web Config File:

When using the Active Directory Provider you will be required to modify the Web config to map the Failed Password Answer Count, Failed Password Answer Time and Failed Password Answer Lockout Time attributes to the appropriate User’s properties (as created above) in either your Active Directory or ADAM.

 

<membership defaultProvider="ADAMProvider">

   <providers>

      <add

         connectionStringName="ADCnString"

         connectionUsername="CN=ADAdmin,OU=Users,O=ADAuth"

         connectionPassword=Pass@word1

       connectionProtection="None"

       requiresQuestionAndAnswer="true"

       enablePasswordReset="true"

          attributeMapPasswordQuestion="PwdQuestion"

          attributeMapPasswordAnswer="PwdAnswer"

attributeMapFailedPasswordAnswerCount="FailedPwdCount" attributeMapFailedPasswordAnswerTime="FailedPwdAnswerTime"

attributeMapFailedPasswordAnswerLockoutTime="FailedPwdLockOutTime"

 

Local Account Policy:

When using ADAM on Windows 2003 you need to set the Account Lockout parameters via the Local Account Policy under the local Administration Tools.  There are three parameters that will need to be configured:

 

  • The value specified in Account Lockout threshold will map to Failed Password Answer Count attributes.
  • The value of the Account Lockout duration will map to the Failed Password Answer Lockout Time. 
  • Finally, the value for the Reset Account lockout counter will map to the Failed Password Answer Time. 

For example, if an user types in three invalid password in a 30 minute span between each attempt the password will be locked out for 30 minutes unless otherwise enabled.

 

Once the Schema has been created, the webconfig modified to map the attributes to the schema and the local account policy password lockout is activated, it is now possible to lockout accounts after failed password attempts.

 

Manually Unlock User Accounts:

 

The following is an example Web Page that displays all Members stored in ADAM as well as whether they are unlocked or not.  In addition, it also includes the example code to manually unlock the user.

 

Example Web Page:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"

        OnSelectedIndexChanged="GridView1_SelectedIndexChanged">

        <Columns>

            <asp:BoundField DataField="UserName" HeaderText="User Name" />

            <asp:BoundField DataField="Email" HeaderText="Email" />

            <asp:BoundField DataField="PasswordQuestion" HeaderText="Password Question" />

            <asp:CheckBoxField DataField="IsLockedOut" HeaderText="Locked Out" />

            <asp:CommandField ButtonType="Button" HeaderText="UnLock User" SelectText="UnLock"

                ShowSelectButton="True" />

        </Columns>

</asp:GridView>

 

Page Load Event Handler Code:

       Dim UserTable As New DataTable

       Dim UserRow As DataRow

        UserTable.Columns.Add("UserName")

        UserTable.Columns.Add("Email")

        UserTable.Columns.Add("PasswordQuestion")

        UserTable.Columns.Add("IsLockedOut")

        Dim mc As MembershipUserCollection = Membership.GetAllUsers()

        For Each User As MembershipUser In mc

            UserRow = UserTable.NewRow

            UserRow(0) = User.UserName

  UserRow(1) = User.Email

            UserRow(2) = User.PasswordQuestion

            UserRow(3) = User.IsLockedOut

            UserTable.Rows.Add(UserRow)

        Next

        GridView1.DataSource=UserTable

            GridView1.DataBind

Gridview Command Button Event Handler:

Dim username as String=GridView1.SelectedRow.Cells(0).Text

Dim User As MembershipUser = Membership.GetUser(username)

        If User.IsLockedOut Then

            User.UnlockUser()