Click here to Skip to main content
14,236,142 members

Custom Authentication and Authorization in MVC 5

Rate this:
4.00 (22 votes)
Please Sign up or sign in to vote.
4.00 (22 votes)
11 Jul 2016CPOL
Here I explain how to create custom authentication and mapping it to the default filters like Authorize, roles..etc

Introduction

There are certain scenario's in our projects we which needs to used for custom Authentication instead of using Default MVC5 Asp.net Identity mechanism. So here I am explaining on how to create custom authentication and mapping it to the default filters like Authorize, roles..etc.

Steps to follow

  1. Open visual studio create a new project

2. Select ASP.NET Application and name the project

3. Select MVC template

4. After loading the project , create a new folder DAL (Here we can call our custom implementation methods for User Authentication)

5. Now project structure looks like the below diagram in solution explorer

6. Add two classes in DAL layer, User.cs and Repository.cs 

7. Paste the below code in User.cs file

public class User
{
    public string Email { get; set; }
    public string Roles { get; set; }
    public string Password { get; set; }
}

8. Paste the below code in Repository.cs file

public static class Repository
{
   static List<User> users = new List<User>() {

        new User() {Email="abc@gmail.com",Roles="Admin,Editor",Password="abcadmin" },
        new User() {Email="xyz@gmail.com",Roles="Editor",Password="xyzeditor" }
    };

    public static User GetUserDetails(User user)
    {
        return users.Where(u => u.Email.ToLower() == user.Email.ToLower() &&
        u.Password == user.Password).FirstOrDefault();
    }
}

9.  Open  “AccountController” in Controllers folder.

10.  Goto method called Login(LoginViewModel model, string returnUrl)

Delete the below code from the Login method

11. Paste the below code inside login method

if (!ModelState.IsValid)
{
    return View(model);
}

User user = new User() { Email=model.Email,Password=model.Password};

user = Repository.GetUserDetails(user);

if (user!=null)
{
    FormsAuthentication.SetAuthCookie(model.Email, false);

    var authTicket = new FormsAuthenticationTicket(1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(20), false, user.Roles);
    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
    HttpContext.Response.Cookies.Add(authCookie);
    return RedirectToAction("Index", "Home");
}

else
{
    ModelState.AddModelError("", "Invalid login attempt.");
    return View(model);
}
  1. Goto public ActionResult LogOff() method in AccountController itself

        Replace existing code with below code

//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    //AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}
  1. Open Global.asax.cs file

 Paste the below method

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        if (authTicket != null && !authTicket.Expired)
        {
            var roles = authTicket.UserData.Split(',');
            HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
        }
    }
}

Now the settings required for Authentication and roles have been completed.

Lets see what have we created and how are we going to use those

1.    We have created 2 users Admin,Editor in Repository.cs class

2.    Now In Home Controller “Index” method we will give access to only “Admin” ,for “About” method will give access to both “Admin and Editor”.

Decorate HomeController with [Authorize] attribute first to restrict unauthorized access, decorate remaining two methods with respective roles as discussed above.

See the below code snippet for reference

[Authorize]

public class HomeController : Controller
    [Authorize(Roles = "Admin")]
    public ActionResult Index()
    {
        return View();
    }

    [Authorize(Roles = "Admin,Editor")]
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";

        return View();
    }

That’s it, our application is ready with custom authentication and authorization.

Now let’s run the application, as we have decorated HomeControllerwith [Authorize] attribute, we will get Login page first instead of Default HomeController Index method.

If we see the url it is not directly called Account/Login method, there is extra ReturnUrl

http://localhost:51581/Account/Login?ReturnUrl=%2F

See default route config as below

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

So when it goes to HomeController directly it doesn’t get authenticated so it redirects to Login page in AccountController. Now enter the required credentials created by us. I am entering admin details i.e.

Now when we click the Login Button, it will redirect to Index method in HomeController.

When we see extreme right corner , it will read the User details from context and Hello abc@gmail.com!

Now Logoff and enter editor credentials.

When we click on Login Page we will be same screen, but Right side we can see User is authenticated (Hello xyz@gmail.com!), because he doesn’t have permission to call Index method it will show the same page.

Now just Point the Url to HomeController, “About” method as below.

http://localhost:51581/Home/About

we will be redirected to desired page, since “Editor” role has permission he can access the About Action method.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

Comments and Discussions

 
QuestionUnable to find userData from FormsAuthenticationTicket Pin
Dharmendra Kumar singh1-May-18 23:11
memberDharmendra Kumar singh1-May-18 23:11 
AnswerRe: Unable to find userData from FormsAuthenticationTicket Pin
satya inumarthi24-Aug-18 1:39
membersatya inumarthi24-Aug-18 1:39 
Praisethanks. Pin
yenai29-Mar-18 4:41
memberyenai29-Mar-18 4:41 
PraiseGreat article Pin
tahirk55518-Mar-18 2:34
professionaltahirk55518-Mar-18 2:34 
QuestionNice Pin
Member 441421819-Dec-17 3:20
memberMember 441421819-Dec-17 3:20 
Questionlogin Pin
Member 1316687110-Dec-17 4:59
memberMember 1316687110-Dec-17 4:59 
AnswerRe: login Pin
satya inumarthi31-Dec-17 22:33
membersatya inumarthi31-Dec-17 22:33 
PraiseThanks, Satya Pin
tyolu9-Nov-17 22:52
membertyolu9-Nov-17 22:52 
QuestionGreat Tutorial! But there is another way also Pin
Member 1174823810-Sep-17 1:09
memberMember 1174823810-Sep-17 1:09 
QuestionThank you. Pin
Nileshbhai29-Jun-17 2:23
professionalNileshbhai29-Jun-17 2:23 
QuestionHow to specify the redirect page if authentication failed? Pin
Member 1300601820-Apr-17 5:43
memberMember 1300601820-Apr-17 5:43 
QuestionWant to use Database first approach instead of repository class Pin
Mgkvp7-Apr-17 2:35
memberMgkvp7-Apr-17 2:35 
QuestionThanks very helpful Pin
Member 130375473-Mar-17 23:56
memberMember 130375473-Mar-17 23:56 
QuestionThank you Pin
saad_rahmouni24-Feb-17 6:12
membersaad_rahmouni24-Feb-17 6:12 
PraiseGreat Work! A small suggestion to use FormsAuthentication class Pin
Anchit Sood (Member 12832613)15-Jan-17 8:08
memberAnchit Sood (Member 12832613)15-Jan-17 8:08 
QuestionWhat is Repository.cs Pin
Manav Pandya18-Dec-16 20:27
memberManav Pandya18-Dec-16 20:27 
AnswerRe: What is Repository.cs Pin
antonio6t4-Jan-17 11:51
memberantonio6t4-Jan-17 11:51 
Questionthanks Pin
Member 128157917-Nov-16 19:55
memberMember 128157917-Nov-16 19:55 
PraiseBig thanks to you Pin
OscarG22-Oct-16 8:23
memberOscarG22-Oct-16 8:23 
PraiseThanks Pin
RAFUBE16-Jul-16 8:40
memberRAFUBE16-Jul-16 8:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 11 Jul 2016

Stats

162.2K views
8.1K downloads
29 bookmarked