A day with .Net

My day to day experince in .net

Custom Form Authentication in MVC 4 with Custom Authorize Attribute and Session Variable.

Posted by vivekcek on June 29, 2013

Good afternoon dears,

Today i am going to write about how you can implement a custom authentication in MVC.

1. Create an Empty MVC 4 project. Why we use Empty Project Template? because we don’t want to add default LoginControllers in MVC.

2. Create a new model class ‘User’. Place the class in Models folder.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace CustomAuthetication.Models
{
    public class User
    {
        public int UserId { get; set; }

        [Required]
        public string UserName { get; set; }

        [Required]
        public string Password { get; set; }

        public bool RememberMe { get; set; }
    }
}

3. Create a class named CustomAuthorize and, place it in solution with out any namespace.

Our custom authorize attribute not only check the form authentication cookie but also check a Session variable named ‘User’.
We save an instance of our User class in this session variable on successful login.So if this session variable is null, that means session has expired

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CustomAuthetication
{
    public class CustomAuthorize : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var authroized = base.AuthorizeCore(httpContext);
            if (!authroized)
            {
                // the user is not authenticated or the forms authentication
                // cookie has expired
                return false;
            }

            // Now check the session:
            var myvar = httpContext.Session["User"];
            if (myvar == null)
            {
                // the session has expired
                return false;
            }

            return true;
        }
    }

}

4. Create a Controller named HomeController and decorate it’s actions with [CustomAuthorize]. Also add a view for the Index action.This home page is available only for authorized users.

public class HomeController : Controller
    {
        //
        // GET: /Home/
        [CustomAuthorize]
        public ActionResult Index()
        {
            return View();
        }

    }

5. Now create a controller named LoginController.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CustomAuthetication.Models;
using System.Web.Security;

namespace CustomAuthetication.Controllers
{
    public class LoginController : Controller
    {
        static List<User> Users = null;

        public LoginController()
        {
            Users = new List<User> { new User{ UserId=1,UserName="vivek",Password="vivek"},
            new User{ UserId=1,UserName="chanthu",Password="chanthu"},
            new User{ UserId=1,UserName="ramu",Password="ramu"},
            };
        }

        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Login(User tempUser, string ReturnUrl)
        {
            if (ModelState.IsValid)
            {
                User user = Users.FirstOrDefault(x => x.UserName == tempUser.UserName & x.Password == tempUser.Password);
                if (user != null)
                {
                    Session["User"] = user;
                    FormsAuthentication.SetAuthCookie(user.UserName, tempUser.RememberMe);
                    return Redirect(ReturnUrl);
                }
                else
                {
                    ModelState.AddModelError("", "Log In Failed");
                }
            }
            else
            {
                ModelState.AddModelError("", "Log In Failed");
            }

            return View();
        }

        public ActionResult Logout()
        {
            Session["User"] = null;
            FormsAuthentication.SignOut();
            return View();
        }

    }
}

6. Add View for Login action in LoginController.

@model CustomAuthetication.Models.User
@{
    ViewBag.Title = "Login";
    
}
@using (Html.BeginForm(new { ReturnUrl = Request.QueryString["ReturnUrl"] }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
   
    <div class="Container">
        <div class="login">
            <h1>
                Log In</h1>
            <p>
                @Html.TextBoxFor(m =>m.UserName , new { placeholder = "User Name" })
                @Html.ValidationMessageFor(m => m.UserName)
            </p>
            <p>
                @Html.PasswordFor(m => m.Password, new { placeholder = "Password" })
                @Html.ValidationMessageFor(m => m.Password)
            </p>
            <p class="rememeber_me">
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe)
            </p>
            <p class="submit">
            <input type="submit" value="Log in" />
            </p>
        </div>
    </div>
}

7. Now in web config enable form authentication.

<authentication mode="Forms">
      <forms loginUrl="~/Login/Login"></forms>
    </authentication>

8. Solution Structure.

sol

Advertisements

11 Responses to “Custom Form Authentication in MVC 4 with Custom Authorize Attribute and Session Variable.”

  1. Ram said

    This article explains the concept in a simple clear way. But some how it does not works for me. Can you send me the solution for the same or upload here?

  2. Phalguni Bhuyan said

    Very nice one. I got more understanding about Authentication in MVC

  3. Thank you, this exactly describes what I’m trying to do! This should adapt well to my solution.

    BTW, the one thing missing is an Index view for HomeController. Maybe that’s what “Ram” was having issues with.

    • John said

      Do you know what could be causing this error?
      HTTP Error 500.19 – Internal Server Error
      The requested page cannot be accessed because the related configuration data for the page is invalid.

  4. Session variables are null at the Authorize stage

  5. Simple and useful . thanks 🙂

  6. jangya said

    Very nice tutorial
    but if i want to deny some actions like dont show again login page after logged in then what should i do..

    • pete said

      I don’t know if you got your answer yet, but I would think that you need to put something like

      @if (Session[“User”] != null)
      {
      @Html.ActionLink(“Logout”, “Logout”, “Login”)
      }
      To show the link to log out. Just play with the values a bit in you shared layout file to turn things on and off if the user is logged in

      For each action and/or controller that you want secured you need to put in the custom attribute of [CustomAuthorize]

  7. pete said

    This works just like expected with ASP.NET MVC 5. Thanks so much for the nice clean example that show the basics. I’m going to extend this to use MySQL databases for the user accounts, which won’t be too hard to do expecially if becuase I’m going to use Dapper.

  8. Nishith konar said

    Many thanks to you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s