|
After running the Role-Based Security Wizard and rebuilding your application, open the App_Code\Shared\SignIn_Control.Controls.cs
page in Visual Studio 2005. (Fig. 5)

Fig. 5 – Empty SignIn_Control class.
Add “using” clauses at the top and override the Login method by typing the word “override” within the public class in Section 1.
Then, press the spacebar, and a list of all the routines that can be overridden will pop up. Since there are two overrides for
the Login method, be sure to override the signature that has bRedirectOnSuccess as a parameter. After highlighting the proper
signature, press Enter and Visual Studio will automatically add the basic code ‘hook’ where we can place our custom LDAP logic.

Fig. 6 – Empty Login Override.
We’ve just added to the existing code that will be executed after the user clicks the SignIn button on the SignIn page. It is
currently nearly empty – with only a single call to the ‘base’ (overridden) login code. The login code in that is overridden is
located in Section 2, so the call to the base.Login method can be viewed by expanding the Section 2 Region.
Next, we need to fill in the Login routine with the code that hits the LDAP server. If we just call the base.Login routine (as is
coded now), we will loose control and the Iron Speed Designer standard authentication will take place based on the rules and fields
configured in the Role-Based Security Wizard. During this default process, the user is automatically redirected. This is not what
we want, so we will locate and copy the base.Login contents and paste it in our override Login method, then modify the overridden code
as needed to look at the LDAP server first.
IMPORTANT NOTE: We will not make any changes to the Section 2 code at the bottom of the page; we will only COPY the code from Section 2,
paste it into our overridden method which is in Section 1 and modify the copy in Section 1. We will not even call the original code located
in Section 2, since we have pasted the same code into Section 1 and is soon to be modified to work the way we want.
Next, we’ll mix in the DirectoryServices (LDAP) code to authenticate and perform the directory search. This will be done in the Section
1 Login code.
public override void Login(bool bRedirectOnSuccess)
{
string strUserName = this.UserName.Text;
string strPassword = this.Password.Text;
string errMessage = "";
if ((strUserName == "" | strPassword == ""))
{
ProcessLoginFailed(ERR_INVALID_LOGIN_INFO, strUserName);
}
string clientIPAddress = this.Page.Request.ServerVariables["REMOTE_ADDR"] + " (HTML)";
string strUserId = "";
// THIS IS WHERE WE NEED TO INSERT OUR LDAP CODE; AFTER WE COLLECT // THE USERNAME AND PASSWORD FROM THE SCREEN, BUT BEFORE THE CALL
// TO SetLoginInfo (below) WHICH IS IRON SPEED DESIGNER’S ROLE BASED
// SECURITY METHOD OF SIGNING A USER IN.
bool bSuccess = false;
try
{
bSuccess = ((BaseApplicationPage)(this.Page)).SystemUtils.SetLoginInfo(strUserName, "1", ref errMessage);
}
catch (System.Threading.ThreadAbortException ex)
{
throw;
}
catch (System.Exception e)
{
ProcessLoginFailed(ERR_INTERNAL_ERROR + " " + e.Message, "");
}
if ((bSuccess))
{
// WE MUST REMOVE THE LINES BELOW IN RED.
if (LoginSucceeded != null)
{
LoginSucceeded(this, new System.EventArgs());
}
if (bRedirectOnSuccess)
{
RedirectOnSuccess();
}
}
else
{
if (!(errMessage == null && errMessage != ""))
{
ProcessLoginFailed(errMessage, strUserName);
}
else
{
ProcessLoginFailed(ERR_INVALID_LOGIN_INFO, strUserName);
}
}
}
|
Example 1 – Login Override that is a Copy of the Section 2 Login Routine.
Instead of typing in the code as it appears in Fig. 7, it is much safer to copy your own application’s Login routine from
Section 2. This will ensure that you will have the properly running, latest code if Iron Speed Designer makes any future
changes to the logic herein.
If the user cannot be authenticated on the LDAP server with the UserName and Password that they supplied, an exception will
be thrown and the code below the red box will NOT be executed. They will only be signed-in and redirected to the proper page
after a successful authentication against the LDAP server.

Fig. 7 – Insert DirectoryServices (LDAP) Logic.
We must mix our new logic right in with the existing code in the Section 1 Login override.
If your LDAP server requires a specific type of Authentication (Secure Sockets, FastBind, etc.) you can provide that parameter
AFTER the strPassword parameter (e.g. AuthenticationTypes.SecureSocketsLayer). If you are not sure which Authentication Type your
server uses, either contact your IT department or do a little trial-and-error. Be careful though – if your network’s policy locks
your user account after three bad login attempts, you could be kicked off the network!
Remove the LoginSucceeded logic since this is no longer necessary (and will prevent the project from compiling since the LoginSucceeded
objects are only in Section 2).

Fig. 8 – LoginSucceeded Logic that Needs Removing.
Remove the following code, which can be found in the Section 1 Login override method.
Contents of Login Method in C#:
public override void Login(bool bRedirectOnSuccess)
{
string strUserName = this.UserName.Text;
string strPassword = this.Password.Text;
string errMessage = "";
if ((strUserName == "" | strPassword == ""))
{
ProcessLoginFailed(ERR_INVALID_LOGIN_INFO, strUserName);
}
string clientIPAddress = this.Page.Request.ServerVariables["REMOTE_ADDR"] + " (HTML)";
string strUserId = "";
// Here is where the users Active Directory name and password are
// checked against the LDAP server.
DirectoryEntry entry = new DirectoryEntry("LDAP://engineering.mycompany.com",
strUserName, strPassword);
DirectorySearcher mySearcher = new DirectorySearcher(entry);
try
{
// Search the directory - simply searches by username, not
// password.
SearchResultCollection results = mySearcher.FindAll();
// If we have any results, then we successfully authenticated to
// the LDAP server (meaning that the supplied users name and
// password are valid on the network) and we found the unique
// username on the LDAP server.
if (results.Count == 0)
{
throw new ApplicationException("Unknown User Name or bad password for user: " + strUserName);
}
}
catch (System.Exception ex)
{
throw new ApplicationException("Unknown User Name or bad password for user: " + strUserName);
}
bool bSuccess = false;
try
{
bSuccess = ((BaseApplicationPage)(this.Page)).SystemUtils.SetLoginInfo(strUserName, "1", ref errMessage);
}
catch (System.Threading.ThreadAbortException ex)
{
throw;
}
catch (System.Exception e)
{
ProcessLoginFailed(ERR_INTERNAL_ERROR + " " + e.Message, "");
}
if ((bSuccess))
{
if (bRedirectOnSuccess)
{
RedirectOnSuccess();
}
}
else
{
if (!(errMessage == null && errMessage != ""))
{
ProcessLoginFailed(errMessage, strUserName);
}
else
{
ProcessLoginFailed(ERR_INVALID_LOGIN_INFO, strUserName);
}
}
}
|
Example 2 – Login Override that is Complete Including LDAP Logic.
Build and Run your application. When the SignIn page appears, test your network username and network password.
If you are afraid that any user can just type a “1” as the password (in the event the user somehow knows we tied
the Role-Based Security to the IsActive database field), you can test now and see that no sign-in is granted with
such a password. This is because the sign-in will throw an exception if this UserName and Password combination fails
to authenticate against the LDAP server. This exception will cause the SetLoginInfo (the Iron Speed Designer Role-Based
Security code) to be bypassed. Again, be careful not to lock your Windows account.
NOTE: If, after testing your application with some bad passwords, you find that you get an error when you try to print to
your office printer, or get a strange error when trying to access your network drives, this is likely because your account
got locked while you were testing.
|