Thursday 19 November 2015

Forms Authentication in ASP.net MVC

 

               In my previous article I explain, what the disadvantages of Webforms are and what the advantages of using ASP.net MVC etc. In this article I'm moving further like security level. We all off us know that we have Authentication and Authorization concepts in ASP.net to verify the security level settings. In this article I'm going to explain FormAuthentication in ASP.net MVC.



 

Forms Authentication in ASP.net MVC:


 

Summary:

           In my previous article I explain, what the disadvantages of Webforms are and what the advantages of using ASP.net MVC etc. In this article I'm moving further like security level. We all off us know that we have Authentication and Authorization concepts in ASP.net to verify the security level settings. In this article I'm going to explain FormAuthentication in ASP.net MVC.
 
 

Agenda:


Implement Form based Authentication in ASP.net MVC to validate the logins with simple example.
 


What is Forms Authentication in ASP.net Webforms:


  • End user make a request, then browser will send the associated cookie stored in the client machines.
  • When request is received from server end, server examines the request and validate for the "Authentication Cookie".
  • If cookie is found, server confirms the identity of the users, and allows him/ her to further process.
  • If cookie is not found, then server confirms that user is an unauthenticated user. In this case will redirect him back to login page again.

     

    Note: The best example of Form authentication is Gmail account, Yahoo account or any login based forms.

     

    Follow below steps to understand more about Forms Authentication

     

    Step 1 – Create AuthenticationController and Login action method




     

    Right click on Controller folder and add new Controller name it as "AuthenticationController".     

     
     
     
    Inside that create a new Action method name as "Login" as follows.    
     
     namespace MVCProject.Controllers  
     {  
       public class AuthenticationController : Controller  
       {      
         // GET: Authentication  
         public ActionResult Login()  
         {  
           return View();  
         }  
       }  
     }  
    
     

    Step 2 – Create new Model


    Create new model class name as "UserDetails" inside Model folder as follows.
     
     
     namespace MVCProject.Models  
     {  
       public class UserDetails  
       {  
         public string UserName { get; set; }  
         public string Password { get; set; }  
       }  
     }  
    
     

    Step 3 – Create new View



    Create new View inside "~/Views/Authentication" folder and give a name as "Login" and design it as like below.
     
     
     
     
     
     @model MVCProject.Models.UserDetails  
     @{  
       Layout = null;  
     }  
     <!DOCTYPE html>  
     <html>  
     <head>  
       <meta name="viewport" content="width=device-width" />  
       <title>Login</title>  
     </head>  
     <body>  
       <div>   
         @using(Html.BeginForm("DoLogin","Authentication",FormMethod.Post))  
         {  
           @Html.LabelFor(c=>c.UserName)  
           @Html.TextBoxFor(x=>x.UserName)  
           <br/>  
           @Html.LabelFor(c=>c.Password)  
           @Html.TextBoxFor(x=>x.Password)  
           <br/>  
           <input type="submit" name="BtnSubmit" value="Login" />  
         }  
       </div>  
     </body>  
     </html>  
    
     
    Keep the view as strongly typed view by adding below lines of code.
     
     @model MVCProject.Models.UserDetails  
    


    As you seen in above view, instead of pure HTML we are generating HTMLHelper class.
    Ex:
     @Html.LabelFor(c=>c.UserName)  
    
     
    Above code will generate the following HTML  
     <input type="text" id="UserName" name="UserName" Value=""/>  
    
     

    Step 4 – Enable Forms Authentication



            Until now we are preparing the login screen, now we need to perform authentication based on login entries. The best approach is using Forms Authentication.


    Open Web.Config and find the "System.Web" inside that search the tag "authentication" if it's not exists create it and make the mode as "Forms" and give the formsloginurl "Authentication/Login".


    In above loginurl "Authentication" is pointing the controller name whereas "Login" is pointing the Action method of the Controller.
       
     
     <system.web>  
       <authentication mode="Forms" >  
        <forms loginUrl="Authentication/Login"></forms>  
       </authentication>  
       <compilation debug="true" targetFramework="4.5" />  
       <httpRuntime targetFramework="4.5" />  
      </system.web>  
    
     

    Step 5 – Make Action method secured



    Create one more controller and give name it as "StudentController" and implement the code like below, make Index Action method as secure by using "Authorize" attribute.
     
     
     
     namespace MVCProject.Controllers  
     {  
       public class StudentController : Controller  
       {  
         [Authorize]  
         public ActionResult Index()  
         {  
           StudentListViewModel objStdlstVM = new StudentListViewModel();  
           StudentBusinessLayer objStdBL = new StudentBusinessLayer();  
           List students = objStdBL.BALGetStudents();  
           List stdViewmodels = new List();  
           foreach (Student std in students)  
           {  
             StudentViewModel stdViewModel = new StudentViewModel();  
             stdViewModel.StudentId = std.StudentId.ToString();  
             stdViewModel.StudentName = std.StudentName;  
             stdViewModel.Course = std.Course;  
             stdViewmodels.Add(stdViewModel);  
           }  
           objStdlstVM.Students = stdViewmodels;  
           return View("Index", objStdlstVM);  
         }  
         public ActionResult AddNew()  
         {  
           return View("CreateStudent");  
         }  
         public ActionResult SaveStudent(Student s, string BtnSave)  
         {  
           switch (BtnSave)  
           {  
             case "Save Student":  
               if (ModelState.IsValid)  
               {  
                 StudentBusinessLayer stdBAL = new StudentBusinessLayer();  
                 stdBAL.SaveStudent(s);  
                 return RedirectToAction("Index");  
               }  
               else  
               {  
                 return View("CreateStudent");  
               }  
             case "Cancel":  
               return RedirectToAction("Index");  
           }  
           return new EmptyResult();  
         }  
       }  
     }  
    
     
     

    Step 6 – Execute and Test


    Run the StudentController directly without login and see the difference.
     

    Step 7 – Create Business Layer functionality


    I have already created "StudentBusinessLayer" inside model folder, open it and implement the below part of code into that.
     
     
     
     
     namespace MVCProject.Models  
     {  
       public class StudentBusinessLayer  
       {  
         public bool IsValidUser(UserDetails u)  
         {  
           if (u.UserName == "Admin" && u.Password == "Welcome")  
           {  
             return true;  
           }  
           else  
           {  
             return false;  
           }  
         }  
          ……………..  
       }  
     }  
    
     
     
    Note: In my above business logic I have given hard coded credentials, in real time you can get back from database and verify it.


    Step 8 – Create DoLogin Action method



    Open AuthenticationController and create new action method name it as "DoLogin" as follows.
     
     
     
     namespace MVCProject.Controllers  
     {  
       public class AuthenticationController : Controller  
       {      
         // GET: Authentication  
         public ActionResult Login()  
         {  
           return View();  
         }  
         [HttpPost]  
         public ActionResult DoLogin(UserDetails u)  
         {  
           StudentBusinessLayer stdBAL = new StudentBusinessLayer();  
           if (stdBAL.IsValidUser(u))  
           {  
             ///create a cookie in client machine  
             FormsAuthentication.SetAuthCookie(u.UserName, false);  
             ///Redirect to the StudentController and Action method Index  
             return RedirectToAction("Index", "Student");  
           }  
           else  
           {  
             ///Model State error details  
             ModelState.AddModelError("CredentialError", "Invalid Username or Password");  
             return View("Login");  
           }  
         }  
       }  
     }  
    
    Note: In above code FormsAuthentication.SetAuthCookie, we are passing 2 parameters.
    First one is login name and second parameter is "Persistent Cookie" i.e. Boolean property.

    • If Persistent Cookie as false, cookie information deleted after closing browser.
    • If Persistent Cookie as true, cookie information won't deleted automatically we need to delete manually or by code.

     

    Step 9 – Error message Validation


     

    In above code, else part we are trying to show error message by using ModelState Key i.e. CredentialError, we need to implement the same in view to show the error logs in output screen.
    Open Login View and place the below code before this line.       
     

     @using (Html.BeginForm("DoLogin", "Authentication", FormMethod.Post));  
     @Html.ValidationMessage("CredentialError", new { style = "color:red;" })  
    
     

    OutPut:

     
     
     
     

    Display Logged-in user and Logout option




    Step 10 – Display Logged in User



    Create a Viewmodel Folder and then create a class name it as "StudentViewModel" and add new property called as UserName. If you want full part of code then download the source code.
      
     
     
     namespace MVCProject.ViewModels  
     {  
       public class StudentListViewModel  
       {  
         public List Students{get; set;}  
         public string UserName { get; set; }  
       }    
     }  
    
     
     

    Step 11 – Set Logged-in User in Controller



    Open StudentController and assign the value to UserName Property which is created in StudentViewModel class.
     
     
     public class StudentController : Controller  
     {  
         [Authorize]  
         public ActionResult Index()  
         {  
           StudentListViewModel objStdlstVM = new StudentListViewModel();  
           objStdlstVM.UserName = User.Identity.Name;  
     …….  
         }  
     }  
    
     

    Step 12 – Display the Logged in user in View



    Open Index.cshtml view and design like below,
     
     
     <div style="text-align:right"> Hello, @Model.UserName </div>  
       <hr />  
       <a href="/Student/AddNew">Add New</a>  
    
     

    Step 13 – Create Logout Link



    Open Index.cshtml view and redesign like below,
     
     
     <div style="text-align:right"> Hello, @Model.UserName   
       <a href="/Authentication/Logout">Logout</a></div>  
       <hr />  
       <a href="/Student/AddNew">Add New</a>  
       ........  
    
     

    Step 14 – Create LogOut Action Method



    Open AuthenticationController and add new Action method as below,
     
     
     public ActionResult Logout()  
     {  
       FormsAuthentication.SignOut();  
       return RedirectToAction("Login");  
     }  
    
     

    Output:

     
     
     

    Q) Does it means Forms Authentication won't work without Cookie



    No, it should work use URI instead of cookie open Web.Config in "forms" tag use "cookieless" attribute to "UseUri".
     
     

    Conclusion:


    I Hope you people are enjoyed with my article, if you have any questions related to this post feel free to contact me by posting comments in the below.

    No comments:

    Post a Comment