DotNetNukeŽ Case Study: Fast Login (VB and C#)

For users who must log into a DotNetNuke website multiple times during the day, a faster login is desirable. The following module creates a cookie that recognizes the user and creates a link that logs the user in with a single click.

Note: Currently this does not work with the Internet Explorer 8 web browser

The Module

After installing the module and placing it on a page in a DotNetNuke website, the following screen is presented:

After entering a valid username and password, the screen changes to this:

Clicking the "Login" link will automatically log the user into the website.

If you examine the browser cookies you will see that a cookie has been created. In the example below a cookie has been created for the "admin" user. The number placed in front of "_admin" is a random number that is stored in the DotNetNuke website for the user. If the number does not match the login will be denied and the cookie erased. The random number for the user in DotNetNuke settings will also be changed so that a brute force password guessing attack is not possible.

Clicking "Clear Fast Login" will remove the cookie.

Hide the Fast Login page

It is not recommended that you make the Fast Login module available to the public. Place this module on a page (Tab) and then in Page Management, set the page to not display on the menu by un-checking the "Include In Menu?" option.

Give your administrators a direct link to the page by navigating to Pages in the Admin menu:

Click on the page to select the page, and then click the spyglass icon (View Selected Page):

The web browser will navigate to the page and you will then have the URL (web address) for the page to provide to your website administrators that you would like to provide fast login to.

Source Code

View.ascx:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="View.ascx.vb" Inherits="DotNetNuke.Modules.FastLogin.View" %>
<asp:Panel ID="pnlLogin" runat="server">
    <table border="0" cellpadding="3" cellspacing="0" summary="SignIn Design Table" width="160">
        <tr>
            <td align="middle" class="SubHead" colspan="2">
                User Name:
            </td>
        </tr>
        <tr>
            <td align="middle" colspan="2">
                <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td>
        </tr>
        <tr>
            <td align="middle" class="SubHead" colspan="2">
                Password:</td>
        </tr>
        <tr>
            <td align="middle" colspan="2">
                <asp:TextBox ID="txtPassword" runat="server" TextMode="Password"></asp:TextBox></td>
        </tr>
        <tr>
            <td align="middle" colspan="2">
            </td>
        </tr>
        <tr>
            <td align="center" colspan="2">
                <asp:Button ID="btnLogin" runat="server" OnClick="btnLogin_Click" Text=" Login " /></td>
        </tr>
        <tr>
            <td align="center" colspan="2">
            </td>
        </tr>
        <tr>
            <td align="center" colspan="2">
                <asp:Label ID="lblLoginError" runat="server" EnableViewState="False" ForeColor="Red"></asp:Label></td>
        </tr>
    </table>
</asp:Panel>
<br />
<asp:Panel ID="pnlLoggedin" runat="server">
    <asp:LinkButton ID="lnkLogin" runat="server" OnClick="lnkLogin_Click">[Login]</asp:LinkButton>&nbsp;
    <asp:LinkButton ID="lnkClearCookie" runat="server" OnClick="lnkClearCookie_Click">[Clear Fast Login]</asp:LinkButton><br />
</asp:Panel>

View.ascx.vb:

'
' DotNetNukeŽ - http://www.dotnetnuke.com
' Copyright (c) 2002-2007
' by DotNetNuke Corporation
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
' DEALINGS IN THE SOFTWARE.
'
 
Imports System
Imports System.Web
Imports System.Web.UI.WebControls
Imports System.Collections.Generic
Imports DotNetNuke
Imports DotNetNuke.Common
Imports DotNetNuke.Security
Imports DotNetNuke.Security.Roles
Imports DotNetNuke.Services.Localization
Imports DotNetNuke.Services.Exceptions
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Entities.Users
Imports System.Collections
Imports System.DirectoryServices
Imports System.Web.UI
Imports DotNetNuke.Security.Membership
 
Namespace DotNetNuke.Modules.FastLogin
 
    Partial Class View
        Inherits DotNetNuke.Entities.Modules.PortalModuleBase
 
        Protected Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim strCookie As String = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"))
 
            If CookieExists(strCookie) Then
                pnlLogin.Visible = False
                pnlLoggedin.Visible = True
            Else
                pnlLogin.Visible = True
                pnlLoggedin.Visible = False
            End If
 
        End Sub
 
#Region "Form Events"
        Protected Sub btnLogin_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLogin.Click
            Dim loginStatus As New Security.Membership.UserLoginStatus()
            Dim objUserInfo As UserInfo = UserController.ValidateUser(PortalId, txtUserName.Text, txtPassword.Text, "", "", Request.UserHostAddress, _
             loginStatus)
 
            'Login Error
            If objUserInfo Is Nothing Then
                lblLoginError.Text = "incorrect username or password"
                txtPassword.Text = ""
                Return
            End If
 
            'Successful login
 
            'Store a random value for this user in settings
            Dim strRandomNumber As String = GetRandomNumber()
 
            Dim objModules As New DotNetNuke.Entities.Modules.ModuleController()
            objModules.UpdateModuleSetting(ModuleId, txtUserName.Text, strRandomNumber)
 
            ' Create the cookie
            Dim strCookie As String = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"))
            '  Store the cookie 
            Dim objCookie As New HttpCookie(strCookie)
            objCookie.Value = strRandomNumber + "_" + txtUserName.Text
            objCookie.Expires = DateTime.MaxValue
            '  never expires
            Response.AppendCookie(objCookie)
 
            pnlLogin.Visible = False
            pnlLoggedin.Visible = True
 
        End Sub
 
        Protected Sub lnkLogin_Click(ByVal sender As Object, ByVal e As EventArgs) Handles lnkLogin.Click
            Dim strCookie As String = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"))
 
            Dim cookie As HttpCookie
            cookie = Request.Cookies(strCookie)
            Dim RandomNumber_UserName As String = cookie.Value
 
            Dim intRandomNumber As Integer = GetRandomNumberFromCookie(RandomNumber_UserName)
            Dim strUserName As String = GetUsernameFromCookie(RandomNumber_UserName)
 
            'Get the Random Number stored in Settings
            Dim objModules As New DotNetNuke.Entities.Modules.ModuleController()
            Dim intRandomNumberInSettings As Integer = Convert.ToInt32(objModules.GetModuleSettings(ModuleId)(strUserName))
 
            ' Check to see if the Random Number matches the one stored in Settings
            If intRandomNumber <> intRandomNumberInSettings Then
                pnlLogin.Visible = True
                pnlLoggedin.Visible = False
                lblLoginError.Text = "incorrect check code for the cookie"
                If CookieExists(strCookie) Then
                    Response.Cookies(strCookie).Expires = DateTime.Now.AddDays(-1)
                End If
                'Change the module setting so a hacker is now chasing a moving target
                objModules.UpdateModuleSetting(ModuleId, strUserName, GetRandomNumber())
                Return
            End If
 
            'Log the user in
            Dim objUserInfo As UserInfo = UserController.GetUserByName(PortalId, strUserName)
            UserController.UserLogin(PortalId, objUserInfo, PortalSettings.PortalName, Request.UserHostAddress, True)
 
            Response.Redirect(Globals.NavigateURL(), True)
        End Sub
 
        Protected Sub lnkClearCookie_Click(ByVal sender As Object, ByVal e As EventArgs) Handles lnkClearCookie.Click
            Dim strCookie As String = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"))
 
            If CookieExists(strCookie) Then
                Response.Cookies(strCookie).Expires = DateTime.Now.AddDays(-1)
            End If
 
            pnlLogin.Visible = True
            pnlLoggedin.Visible = False
        End Sub
#End Region
 
#Region "Utility"
        Private Function CookieExists(ByVal strCheckCookie As String) As Boolean
            If (Request.Cookies(strCheckCookie) Is Nothing) Then
                Return False
            Else
                Return True
            End If
        End Function
 
        Protected Function GetRandomNumber() As String
            Dim RandomClass As New Random()
            Dim intRandomNumber As Integer
            intRandomNumber = RandomClass.[Next]()
            Return Convert.ToString(intRandomNumber + ModuleId)
        End Function
 
        Protected Function GetRandomNumberFromCookie(ByVal strCookie As String) As Integer
            Return Convert.ToInt32(strCookie.Substring(0, strCookie.IndexOf("_")))
        End Function
 
        Protected Function GetUsernameFromCookie(ByVal strCookie As String) As String
            Return strCookie.Substring(strCookie.IndexOf("_") + 1, strCookie.Length - (strCookie.IndexOf("_")) - 1)
        End Function
#End Region
 
    End Class
End Namespace

View.ascx.cs:

using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using DotNetNuke;
using DotNetNuke.Common;
using DotNetNuke.Security;
using DotNetNuke.Security.Roles;
using DotNetNuke.Services.Localization;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Users;
using System.Collections;
using System.DirectoryServices;
using System.Web.UI;
using DotNetNuke.Security.Membership;
 
namespace DotNetNuke.Modules.FastLogin
{
    public partial class View : DotNetNuke.Entities.Modules.PortalModuleBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string strCookie = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"));
 
            if (CookieExists(strCookie))
            {
                pnlLogin.Visible = false;
                pnlLoggedin.Visible = true;
            }
            else
            {
                pnlLogin.Visible = true;
                pnlLoggedin.Visible = false;
            }
 
        }
 
        #region Form Events
        protected void btnLogin_Click(object sender, EventArgs e)
        {
            UserLoginStatus loginStatus = new UserLoginStatus();
            UserInfo objUserInfo = UserController.ValidateUser(PortalId, txtUserName.Text, txtPassword.Text, "", "", Request.UserHostAddress, ref loginStatus);
 
            //Login Error
            if (objUserInfo == null)
            {
                lblLoginError.Text = "incorrect username or password";
                txtPassword.Text = "";
                return;
            }
 
            //Successful login
 
            //Store a random value for this user in settings
            string strRandomNumber = GetRandomNumber();
 
            DotNetNuke.Entities.Modules.ModuleController objModules = new DotNetNuke.Entities.Modules.ModuleController();
            objModules.UpdateModuleSetting(ModuleId, txtUserName.Text, strRandomNumber);
 
            // Create the cookie
            string strCookie = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"));
            //  Store the cookie 
            HttpCookie objCookie = new HttpCookie(strCookie);
            objCookie.Value = strRandomNumber + "_" + txtUserName.Text;
            objCookie.Expires = DateTime.MaxValue;
            //  never expires
            Response.AppendCookie(objCookie);
 
            pnlLogin.Visible = false;
            pnlLoggedin.Visible = true;
 
        }
 
        protected void lnkLogin_Click(object sender, EventArgs e)
        {
            string strCookie = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"));
 
            HttpCookie cookie;
            cookie = Request.Cookies[strCookie];
            String RandomNumber_UserName = cookie.Value;
 
            int intRandomNumber = GetRandomNumberFromCookie(RandomNumber_UserName);
            string strUserName = GetUsernameFromCookie(RandomNumber_UserName);
 
            //Get the Random Number stored in Settings
            DotNetNuke.Entities.Modules.ModuleController objModules = new DotNetNuke.Entities.Modules.ModuleController();
            int intRandomNumberInSettings = Convert.ToInt32(objModules.GetModuleSettings(ModuleId)[strUserName]);
 
            // Check to see if the Random Number matches the one stored in Settings
            if (intRandomNumber != intRandomNumberInSettings)
            {
                pnlLogin.Visible = true;
                pnlLoggedin.Visible = false;
                lblLoginError.Text = "incorrect check code for the cookie";
                if (CookieExists(strCookie))
                {
                    Response.Cookies[strCookie].Expires = DateTime.Now.AddDays(-1);
                }
                //Change the module setting so a hacker is now chasing a moving target
                objModules.UpdateModuleSetting(ModuleId, strUserName, GetRandomNumber());
                return;
            }
 
            //Log the user in
            UserInfo objUserInfo = UserController.GetUserByName(PortalId, strUserName);
            UserController.UserLogin(PortalId, objUserInfo, PortalSettings.PortalName, Request.UserHostAddress, true);
 
            Response.Redirect(Globals.NavigateURL(), true);
        }
 
        protected void lnkClearCookie_Click(object sender, EventArgs e)
        {
            string strCookie = ("_Module" + (PortalId.ToString() + "_" + ModuleId.ToString() + "_FastLogin"));
 
            if (CookieExists(strCookie))
            {
                Response.Cookies[strCookie].Expires = DateTime.Now.AddDays(-1);
            }
 
            pnlLogin.Visible = true;
            pnlLoggedin.Visible = false;
        }
 
        #endregion
 
        #region Utility
        private Boolean CookieExists(string strCheckCookie)
        {
            if ((Request.Cookies[strCheckCookie] == null))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
 
        protected string GetRandomNumber()
        {
            Random RandomClass = new Random();
            int intRandomNumber;
            intRandomNumber = RandomClass.Next();
            return Convert.ToString(intRandomNumber + ModuleId);
        }
 
        protected int GetRandomNumberFromCookie(string strCookie)
        {
            return Convert.ToInt32(strCookie.Substring(0, strCookie.IndexOf("_")));
        }
 
        protected string GetUsernameFromCookie(string strCookie)
        {
            return strCookie.Substring(strCookie.IndexOf("_") + 1, strCookie.Length - (strCookie.IndexOf("_")) - 1);
        }
 
        #endregion
 
    }
}

 

Download the code:

VB: FastLogin_01.00.00_Install.zip

C#: FastLogin_01.00.00_Install_C.zip

[Back to: The ADefWebserver DotNetNuke HELP WebSite]


DotNetNukeŽ is a registered trademark of the DotNetNuke Corporation