Introduction
In this post, I am going to implement Custom Forms authentication in ASP.NET MVC4 application.I often find that developers feel uncomfortable setting up Forms Authentication in their web applications. In ASP.NET default membership provider, Information about users and their roles stored in the predefined table and its not customizable which makes it very complicated to take full control of the database and forms authentication mechanism.
I have split the entire application split into following parts for making things more simple and understandable.
- Part 1 : Implement very simple and easy authentication
- Part 2 : implement custom membership provider
- Part 3 : implement a custom role provider
- Part 4 : Implement a custom user principal and identity
Step - 1 : Create New Project.
Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Basic Application > Select view engine Razor > OKStep-2: Add a new Controller.
Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name (Home) > Select Templete "empty MVC Controller"> Add.Step-3: Add new action into your controller for anonymous user
Here I have used "Index" Action. Please write this following code[AllowAnonymous] //This is for Un-Authorize User public ActionResult Index() { return View(); }
Step-4: Add view for the Action & design.
Right Click on Action Method (here right click on index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.Complete View
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <h3>Welcome Guest - This is for all the anonymous user</h3>
Step-5: Add an another action into your controller for Authorized User (Later we will see Role Based user)
Here I have used "Index" Action. Please write this following code[Authorize] // This is for Authorize user public ActionResult MyProfile() { return View(); }
Step-6: Add view for the Action & design.
Right Click on Action Method (here right click on index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.Complete View
@{ ViewBag.Title = "MyProfile"; } <h2>MyProfile</h2> <h3>Welcome @(Request.IsAuthenticated ? HttpContext.Current.User.Identity.Name : "Guest") - This is for Authorized user </h3>Optional: Here I have added Bootstrap css in the layout page for Responsive design.
Step-7: Create a Class (ViewModel).
Go to Solution Explorer > Right Click on the Models Folder > Add > Class > Enter class name > Add.using System.ComponentModel.DataAnnotations; namespace MvcAuthentication.Models { public class Login { [Required(ErrorMessage="Username required.",AllowEmptyStrings=false)] public string Username { get; set; } [Required(ErrorMessage = "Password required.", AllowEmptyStrings = false)] [DataType( System.ComponentModel.DataAnnotations.DataType.Password)] public string Password { get; set; } public bool RememberMe { get; set; } } }
Step-8: Add an another Controller (here "MyAccountController") for Manage Account Related Action like Login, logout etc.
Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name (MyAccount) > Select Templete "empty MVC Controller"> Add.Step-9: Add a new action into the controller (here "MyAccountController") for Logged In
Here I have used "Login" Action. Please write this following codepublic ActionResult Login() { return View(); }
Step-10: Add view for the "Login" Action & design.
Right Click on Action Method (here right click on index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.Complete View
@model MvcAuthentication.Models.Login @{ ViewBag.Title = "Login"; } <h2>Login</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) @Html.AntiForgeryToken() <fieldset> <legend>Login</legend> <div class="editor-label"> @Html.LabelFor(model => model.Username) </div> <div class="editor-field"> @Html.EditorFor(model => model.Username) @Html.ValidationMessageFor(model => model.Username) </div> <div class="editor-label"> @Html.LabelFor(model => model.Password) </div> <div class="editor-field"> @Html.EditorFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </div> <div class="editor-label"> @Html.LabelFor(model => model.RememberMe) </div> <div class="editor-field"> @Html.EditorFor(model => model.RememberMe) @Html.ValidationMessageFor(model => model.RememberMe) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
Step-11: Edit web.config for Enable Forms authentication.
<authentication mode="Forms"> <forms loginUrl="~/MyAccount/Login" timeout="2880" /> </authentication>
RUN APP HERE FOR TEST IS ALL WORKING AS EXPECTED OR NOT
Step-12: Add a Database for do login from database
Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.Step-13: Create a table.
Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.Step-14: Add Entity Data Model.
Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.
Step-15: Add another action in our controller (here "MyAccountController") for POST method for login from database.
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Login(Login l, string ReturnUrl = "") { using (MyDatabaseEntities dc = new MyDatabaseEntities()) { var user = dc.Users.Where(a => a.Username.Equals(l.Username) && a.Password.Equals(l.Password)).FirstOrDefault(); if (user != null) { FormsAuthentication.SetAuthCookie(user.Username, l.RememberMe); if (Url.IsLocalUrl(ReturnUrl)) { return Redirect(ReturnUrl); } else { return RedirectToAction("MyProfile", "Home"); } } } ModelState.Remove("Password"); return View(); }
Step-16: Add an another action into our controller (here "MyAccountController") for Logout
Here I have used "Logout" Action. Please write this following code[Authorize] public ActionResult Logout() { FormsAuthentication.SignOut(); return RedirectToAction("Index", "Home"); }
Step-17: Update Layout View for Show Login / Logout link.
<li> @{ if (Request.IsAuthenticated) { using (Html.BeginForm("Logout","MyAccount", FormMethod.Post,new{ id = "logoutForm"})) { <a href="javascript:document.getElementById('logoutForm').submit()">Logout</a> } } else { @Html.ActionLink("Login","Login","MyAccount") } } </li>