July 23, 2009
Iron Speed Designer V6.2 and later
A common access control security precaution is to limit the number of times a user is allowed to enter an incorrect user name or password. Once the limit is exceeded, they are locked out for a period of time before they are permitted to attempt logging in again with the same user name. By maintaining a count to ensure that a user should not be allowed more than X attempts in a period of time, you can restrict access when they exceed the allowed number of login attempts.
In the example below, a user is allowed three attempts to enter the correct password. After the third attempt, the user is restricted for a period of one minute.
Step 1: Use the Application Security Wizard (Tools, Application Security Wizard…) to enable application security for your application.
Step 2: In the Application Explorer, select a start page for your application.
Step 3: In the Application Security Wizard, select your start page and set the access permissions for the page as “Grant access only to signed in users”.
Step 4: Override the Login() and ProcessFailedLogin() methods in the SignIn_Control class, located in:
Security\SignIn.aspx.cs (.vb)
C#:
using System; // insert as a first line of the code
public void Login(bool bRedirectOnSuccess)
{
if (isBlocked())
{
BaseClasses.Utils.MiscUtils.RegisterJScriptAlert(this, "my message", "YOU CAN NOT LOGIN NOW");
}
else
{
if (this.Page.Cache["UserKey_" + this.UserName.Text] != null &&
(int)this.Page.Cache["UserKey_" + this.UserName.Text] >3)
{
this.Page.Cache["UserKey_" + this.UserName.Text] = 0;
}
this.Login_Base(redirectOnSuccess);
}
}
public bool isBlocked()
{
object userCounter = this.Page.Cache["UserKey_" + this.UserName.Text];
if ((Convert.ToInt32(userCounter)) >= 3 && (this.Page.Cache["UserBlocked"] != null))
{
return true;
}
return false;
}
protected override void ProcessLoginFailed(string message, string userName)
{
object FailedLoginCounter = this.Page.Cache["UserKey_" + this.UserName.Text];
if (FailedLoginCounter == null)
{
FailedLoginCounter = 0;
}
this.Page.Cache["UserKey_" + this.UserName.Text] = (int)FailedLoginCounter + 1;
if (((int)this.Page.Cache["UserKey_" + this.UserName.Text]) == 3)
{
this.Page.Cache.Insert("UserBlocked", 1, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
}
this.ProcessLoginFailed_Base (message, userName);
}
Visual Basic .NET:
Import System ‘Insert in as a first line of code
Public Sub Login(ByVal bRedirectOnSuccess As Boolean)
If isBlocked Then
BaseClasses.Utils.MiscUtils.RegisterJScriptAlert(Me, "my message", "YOU CAN NOT LOGIN NOW")
Else
If ((Not (Me.Page.Cache(("UserKey_" + Me.UserName.Text))) Is Nothing) _
AndAlso (CType(Me.Page.Cache(("UserKey_" + Me.UserName.Text)),Integer) > 3)) Then
Me.Page.Cache(("UserKey_" + Me.UserName.Text)) = 0
End If
MyBase.Login(bRedirectOnSuccess)
End If
End Sub
Public Function isBlocked() As Boolean
Dim userCounter As Object = Me.Page.Cache(("UserKey_" + Me.UserName.Text))
If ((Convert.ToInt32(userCounter) >= 3) _
AndAlso (Not (Me.Page.Cache("UserBlocked")) Is Nothing)) Then
Return true
End If
Return false
End Function
Protected Overrides Sub ProcessLoginFailed(ByVal message As String, ByVal userName As String)
Dim FailedLoginCounter As Object = Me.Page.Cache(("UserKey_" + Me.UserName.Text))
If (FailedLoginCounter = Nothing) Then
FailedLoginCounter = 0
End If
Me.Page.Cache(("UserKey_" + Me.UserName.Text)) = (CType(FailedLoginCounter,Integer) + 1)
If (CType(Me.Page.Cache(("UserKey_" + Me.UserName.Text)),Integer) = 3) Then
Me.Page.Cache.Insert("UserBlocked", 1, Nothing, DateTime.Now.AddMinutes(1), TimeSpan.Zero)
End If
Me.ProcessLoginFailed_Base (message, userName)
End Sub
Customizing Application Security
Implementing Custom User Authentication
Example: Overriding Security at the Page Level
Example: Programmatically Accessing the Currently Logged-in User
Example: Access User Name and Password from Sign In Control
Example: Allow Only Active Users to Login
Example: Encrypting Passwords Before Saving to the Database
Example: Restrict Login after Incorrect Password Used