Thursday, 13 February 2014

Simple Form based authentication example in ASP.Net

In this article I will explain with example how to implement simple Form based authentication using Login page and Login control in ASP.Net using C#.
The Form based authentication has been implemented using ASP.Net Membership Provider.
Database
I am making use of the same database table Users which was used in the article Simple User Registration Form Example in ASP.Net.
This example consists of two pages Login page (Login.aspx) using which the user will login and the Landing page (Home.aspx) which is the page user will be redirected after successful authentication.
 Login Page
This is the login form which will do the following:-
1. Authenticate user by verifying Username and Password.
2. Make sure user has activated his account. Refer my article for details Send user Confirmation email after Registration with Activation Link in ASP.Net
  HTML Markup
The HTML markup consists of an ASP.Net Login control for which the OnAuthenticate event handler has been specified.
<form id="form1" runat="server">
<asp:Login ID = "Login1" runat = "server" OnAuthenticate= "ValidateUser"></asp:Login>
</form>
Namespaces
You will need to import the following namespaces.
C#
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Security;
Stored Procedure to Validate the User Credentials
The following stored procedure is used to validate the user credentials, this stored procedure first checks whether the username and password are correct else returns -1.
If the username and password are correct but the user has not been activated then the code returned is -2.
If the username and password are correct and the user account has been activated then UserId of the user is returned by the stored procedure.
CREATE PROCEDURE [dbo].[Validate_User]
      @Username NVARCHAR(20),
      @Password NVARCHAR(20)
AS
BEGIN
      SET NOCOUNT ON;
      DECLARE @UserId INT, @LastLoginDate DATETIME
     
      SELECT @UserId = UserId, @LastLoginDate = LastLoginDate
      FROM Users WHERE Username = @Username AND [Password] = @Password
     
      IF @UserId IS NOT NULL
      BEGIN
            IF NOT EXISTS(SELECT UserId FROM UserActivation WHERE UserId = @UserId)
            BEGIN
                  UPDATE Users
                  SET LastLoginDate = GETDATE()
                  WHERE UserId = @UserId
                  SELECT @UserId [UserId] -- User Valid
            END
            ELSE
            BEGIN
                  SELECT -2 -- User not activated.
            END
      END
      ELSE
      BEGIN
            SELECT -1 -- User invalid.
      END
END
Validating the User Credentials
The below event handler gets called when the Log In button is clicked. Here the Username and Password entered by the user is passed to the stored procedure and its status is captured and if the value is not -1 (Username or password incorrect) or -2 (Account not activated) then the user is redirected to the Home page using FormsAuthentication RedirectFromLoginPage method.
C#
protected void ValidateUser(object sender, EventArgs e)
{
    int userId = 0;
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("Validate_User"))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Username", Login1.UserName);
            cmd.Parameters.AddWithValue("@Password", Login1.Password);
            cmd.Connection = con;
            con.Open();
            userId = Convert.ToInt32(cmd.ExecuteScalar());
            con.Close();
        }
        switch (userId)
        {
            case -1:
                Login1.FailureText = "Username and/or password is incorrect.";
                break;
            case -2:
                Login1.FailureText = "Account has not been activated.";
                break;
            default:
                FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
                break;
        }
    }
}
Home Page
After successful login user will be redirected to this page.
 
HTML Markup
In this page I have made use of ASP.Net LoginName control to display the name of the Logged In user and LoginStatus control to allow user Logout.
<div>
    Welcome
    <asp:LoginName ID="LoginName1" runat="server" Font-Bold = "true" />
    <br />
    <br />
    <asp:LoginStatus ID="LoginStatus1" runat="server" />
</div>
Namespaces
You will need to import the following namespaces.
C#
using System.Web.Security;
Verify whether User has Logged In
Inside the Page Load event, first we verify whether the User is authenticated using the IsAuthenticated property. If the user is not authenticated then he is redirected back to the Login page using FormsAuthentication RedirectToLoginPage method.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!this.Page.User.Identity.IsAuthenticated)
    {
        FormsAuthentication.RedirectToLoginPage();
    }
}
Web.Config Configuration
You will need to add the following configuration in the Web.Config file in the <system.web> section.
<authentication mode="Forms">
 <formsdefaultUrl="~/Home.aspx" loginUrl="~/Login.aspx" slidingExpiration="true" timeout="2880"></forms>
</authentication>
 
 

Send user Confirmation email after Registration with Activation Link in ASP.Net

In this article I will explain how to send user confirmation email after registration with Activation link in ASP.Net using C# and VB.Net.
In order to validate the email address of the user provided during registration, a confirmation email with activation link in sent to the email address and when user clicks the link, his email address is verified and his account gets activated.
Database
In the previous article we have already created database named LoginDB which contains the following table named Users in it. For this article I have created a new table named UserActivation.
On the registration page I have made some changes in the RegisterUser event handler, if the username and email address are found valid then the SendActivationEmail method is executed
C#
protected void RegisterUser(object sender, EventArgs e)
{
    int userId = 0;
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("Insert_User"))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Username", txtUsername.Text.Trim());
                cmd.Parameters.AddWithValue("@Password", txtPassword.Text.Trim());
                cmd.Parameters.AddWithValue("@Email", txtEmail.Text.Trim());
                cmd.Connection = con;
                con.Open();
                userId = Convert.ToInt32(cmd.ExecuteScalar());
                con.Close();
            }
        }
        string message = string.Empty;
        switch (userId)
        {
            case -1:
                message = "Username already exists.\\nPlease choose a different username.";
                break;
            case -2:
                message = "Supplied email address has already been used.";
                break;
            default:
                message = "Registration successful. Activation email has been sent.";
                SendActivationEmail(userId);
                break;
        }
        ClientScript.RegisterStartupScript(GetType(), "alert", "alert('" + message + "');", true);
    }
}
Inside the SendActivationEmail method, a unique Activation code is generated using Guid’s NewGuid method and it is inserted in the UserActivation table.
Then an email is sent to the user’s email address with the URL of the Activation page with generated Activation Code in the QueryString of the URL
C#
private void SendActivationEmail(int userId)
{
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    string activationCode = Guid.NewGuid().ToString();
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("INSERT INTO UserActivation VALUES(@UserId, @ActivationCode)"))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddWithValue("@UserId", userId);
                cmd.Parameters.AddWithValue("@ActivationCode", activationCode);
                cmd.Connection = con;
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
            }
        }
    }
    using (MailMessage mm = new MailMessage("sender@gmail.com", txtEmail.Text))
    {
        mm.Subject = "Account Activation";
        string body = "Hello " + txtUsername.Text.Trim() + ",";
        body += "<br /><br />Please click the following link to activate your account";
        body += "<br /><a href = '" + Request.Url.AbsoluteUri.Replace("CS.aspx", "CS_Activation.aspx?ActivationCode=" + activationCode) + "'>Click here to activate your account.</a>";
        body += "<br /><br />Thanks";
        mm.Body = body;
        mm.IsBodyHtml = true;
        SmtpClient smtp = new SmtpClient();
        smtp.Host = "smtp.gmail.com";
        smtp.EnableSsl = true;
        NetworkCredential NetworkCred = new NetworkCredential("sender@gmail.com", "<password>");
        smtp.UseDefaultCredentials = true;
        smtp.Credentials = NetworkCred;
        smtp.Port = 587;
        smtp.Send(mm);
    }
}
 
 Activation email sent to the user
 
 
 
 
 

Simple User Registration Form Example in ASP.Net

In this article I will explain how to build a simple user registration form that will allow user register to the website in ASP.Net using C#.
User will fill up the registration form with details such as username, password, email address, etc. and these details will be saved in the database table.
The registration form will also make sure that duplicate username and email addresses are not saved by verifying whether username and email address must not exists in the table.
 
Database
For this article I have created a new database named LoginDB which contains the following table named Users in it.
 In the above table column UserId is set as primary key and it Identity property is set to true.
 
HTML Markup
The HTML Markup consists of some TextBox, their corresponding Validators and a Button. Other than RequiredField Validators there’s a CompareValidator to compare passwords and a RegularExpressionValidator to validate email address.
<table border="0" cellpadding="0" cellspacing="0">
    <tr>
        <th colspan="3">
            Registration
        </th>
    </tr>
    <tr>
        <td>
            Username
        </td>
        <td>
            <asp:TextBox ID="txtUsername" runat="server" />
        </td>
        <td>
            <asp:RequiredFieldValidator ErrorMessage="Required" ForeColor="Red" ControlToValidate="txtUsername"
                runat="server" />
        </td>
    </tr>
    <tr>
        <td>
            Password
        </td>
        <td>
            <asp:TextBox ID="txtPassword" runat="server" TextMode="Password" />
        </td>
        <td>
            <asp:RequiredFieldValidator ErrorMessage="Required" ForeColor="Red" ControlToValidate="txtPassword"
                runat="server" />
        </td>
    </tr>
    <tr>
        <td>
            Confirm Password
        </td>
        <td>
            <asp:TextBox ID="txtConfirmPassword" runat="server" TextMode="Password" />
        </td>
        <td>
            <asp:CompareValidator ErrorMessage="Passwords do not match." ForeColor="Red" ControlToCompare="txtPassword"
                ControlToValidate="txtConfirmPassword" runat="server" />
        </td>
    </tr>
    <tr>
        <td>
            Email
        </td>
        <td>
            <asp:TextBox ID="txtEmail" runat="server" />
        </td>
        <td>
            <asp:RequiredFieldValidator ErrorMessage="Required" Display="Dynamic" ForeColor="Red"
                ControlToValidate="txtEmail" runat="server" />
            <asp:RegularExpressionValidator runat="server" Display="Dynamic" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
                ControlToValidate="txtEmail" ForeColor="Red" ErrorMessage="Invalid email address." />
        </td>
    </tr>
    <tr>
        <td>
        </td>
        <td>
            <asp:Button Text="Submit" runat="server" OnClick="RegisterUser" />
        </td>
        <td>
        </td>
    </tr>
</table>
Stored Procedure to insert the User details
The following stored procedure is used to insert the user details such as username, password and email address.
The stored procedure first checks whether the username supplied already exists, if yes then it will return negative 1 value.
Then the stored procedure checks whether the email address supplied already exists, if yes then it will return negative 2 value.
If both username and email address are valid then the record will be inserted and the auto-generated UserId will be returned by the stored procedure.
CREATE PROCEDURE [dbo].[Insert_User]
      @Username NVARCHAR(20),
      @Password NVARCHAR(20),
      @Email NVARCHAR(30)
AS
BEGIN
      SET NOCOUNT ON;
      IF EXISTS(SELECT UserId FROM Users WHERE Username = @Username)
      BEGIN
            SELECT -1 -- Username exists.
      END
      ELSE IF EXISTS(SELECT UserId FROM Users WHERE Email = @Email)
      BEGIN
            SELECT -2 -- Email exists.
      END
      ELSE
      BEGIN
            INSERT INTO [Users]
                     ([Username]
                     ,[Password]
                     ,[Email]
                     ,[CreatedDate])
            VALUES
                     (@Username
                     ,@Password
                     ,@Email
                     ,GETDATE())
           
            SELECT SCOPE_IDENTITY() -- UserId                 
     END
END
 
 
Namespaces
You will need to import the following namespaces.
C#
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
 
Inserting the User Details
The following event handler is raised when the submit button is clicked, here the values from the Registration Form’s TextBoxes are passed to the stored procedure and the stored procedure is executed.
The return value from the stored procedure is captured in a variable and then based on its value appropriate message is displayed using JavaScript Alert message box.
C#
protected void RegisterUser(object sender, EventArgs e)
{
    int userId = 0;
    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("Insert_User"))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Username", txtUsername.Text.Trim());
                cmd.Parameters.AddWithValue("@Password", txtPassword.Text.Trim());
                cmd.Parameters.AddWithValue("@Email", txtEmail.Text.Trim());
                cmd.Connection = con;
                con.Open();
                userId = Convert.ToInt32(cmd.ExecuteScalar());
                con.Close();
            }
        }
        string message = string.Empty;
        switch (userId)
        {
            case -1:
                message = "Username already exists.\\nPlease choose a different username.";
                break;
            case -2:
                message = "Supplied email address has already been used.";
                break;
            default:
                message = "Registration successful.\\nUser Id: " + userId.ToString();
                break;
        }
        ClientScript.RegisterStartupScript(GetType(), "alert", "alert('" + message + "');", true);
    }
}
   
Message Box when registration is successful

Message Box when username already exists

Message Box when email address already exists

User record inserted in table