Custom Authentication and Authorization in ASP.NET MVC (2024)

Custom Authentication and Authorization in ASP.NET MVC: An Overview

In this MVC Tutorial, we are going to explain How to create a Custom Authentication app. Authentication and authorization in a website project are still critical to give access to users based on their roles. Enroll yourself into ASP.NET MVC Training program to get deeper understanding of its core concepts.

When standard types of authentication do not meet your requirements, you need to modify an authentication mechanism to create a custom solution. A user context has a principle that represents the identity and roles of that user. A user is authenticated by its identity and assigned roles to a user determine about authorization or permission to access resources.

Custom Authentication and Authorization in ASP.NET MVC (1)

Read More: MVC Interview Questions and Answers

ASP.NET provides IPrincipal and identity interfaces to represent the identity and role of a user. You can create a custom solution by evaluating the IPrincipal and IIdentity interfaces which are bound to the HttpContext as well as the current thread.

public class CustomPrincipal : IPrincipal { public IIdentity Identity { get; private set; } public bool IsInRole(string role) { if (roles.Any(r => role.Contains(r))) { return true; } else { return false; } } public CustomPrincipal(string Username) { this.Identity = new GenericIdentity(Username); } public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string[] roles { get; set; } } 

Now you can put these CustomPrincipal objects into the thread’s current principle property and into the HttpContext’s User property to accomplish your custom authentication and authorization process.

ASP.NET Forms Authentication

ASP.NET forms authentication occurs after IIS authentication is completed. You can configure form authentication by using form elements within the web. config file of your application. The default attribute values for form authentication are shown below:

<system.web><authentication mode="Forms"> <forms loginUrl="Login.aspx" protection="All" timeout="30" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseDeviceProfile" enableCrossAppRedirects="false" /> </authentication></system.web>

The FormsAuthentication class creates the authentication cookie automatically when the SetAuthCookie() or RedirectFromLoginPage() methods are called. The value of the authentication cookie contains a string representation of the encrypted and signed FormsAuthenticationTicket object.

Custom Authentication and Authorization in ASP.NET MVC (2)

You can create the FormsAuthenticationTicket object by specifying the cookie name, version of the cookie, directory path, issue date of the cookie, expiration date of the cookie, whether the cookie should be persisted, and optionally user-defined data as shown below:

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "userName", DateTime.Now, DateTime.Now.AddMinutes(30), // value of time out property false, // Value of IsPersistent property String.Empty, FormsAuthentication.FormsCookiePath);

Now, you can encrypt this ticket by using the Encrypt method FormsAuthentication class as given below:

string encryptedTicket = FormsAuthentication.Encrypt(ticket);

Note

To encrypt the FormsAuthenticationTicket ticket set the protection attribute of the forms element to All or Encryption.

Read More: Introduction to ASP.NET MVC

Custom Authorization

ASP.NET MVC provides an Authorization filter to authorize a user. This filter can be applied to an action, a controller, or even globally. This filter is based on the AuthorizeAttribute class. You can customize this filter by overriding the OnAuthorization() method as shown below:

 public class CustomAuthorizeAttribute : AuthorizeAttribute { public string UsersConfigKey { get; set; } public string RolesConfigKey { get; set; } protected virtual CustomPrincipal CurrentUser { get { return HttpContext.Current.User as CustomPrincipal; } } public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAuthenticated) { var authorizedUsers = ConfigurationManager.AppSettings[UsersConfigKey]; var authorizedRoles = ConfigurationManager.AppSettings[RolesConfigKey]; Users = String.IsNullOrEmpty(Users) ? authorizedUsers : Users; Roles = String.IsNullOrEmpty(Roles) ? authorizedRoles : Roles; if (!String.IsNullOrEmpty(Roles)) { if (!CurrentUser.IsInRole(Roles)) { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" })); // base.OnAuthorization(filterContext); //returns to login url } } if (!String.IsNullOrEmpty(Users)) { if (!Users.Contains(CurrentUser.UserId.ToString())) { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" })); // base.OnAuthorization(filterContext); //returns to login url } } } } }

User Authentication

A user will be authenticated if the IsAuthenticated property returns true. For authenticating a user you can use one of the following two ways:

  1. Thread.CurrentPrincipal.Identity.IsAuthenticated

  2. HttpContext.Current.User.Identity.IsAuthenticated

Designing Data Model

Now it’s time to create data access model classes for creating and accessing Users and Roles as shown below:

public class User { public int UserId { get; set; } [Required] public String Username { get; set; } [Required] public String Email { get; set; } [Required] public String Password { get; set; } public String FirstName { get; set; } public String LastName { get; set; } public Boolean IsActive { get; set; } public DateTime CreateDate { get; set; } public virtual ICollection<Role> Roles { get; set; } }
public class Role { public int RoleId { get; set; } [Required] public string RoleName { get; set; } public string Description { get; set; } public virtual ICollection<User> Users { get; set; } }

Defining Database Context with Code First Mapping between User and Role

Using the Entity Framework code first approach, create a DataContext having User and Role entities with its relational mapping details as shown below:

public class DataContext : DbContext { public DataContext() : base("DefaultConnection") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<User>() .HasMany(u => u.Roles) .WithMany(r=>r.Users) .Map(m => { m.ToTable("UserRoles"); m.MapLeftKey("UserId"); m.MapRightKey("RoleId"); }); } public DbSet<User> Users { get; set; } public DbSet<Role> Roles { get; set; } }

Code First Database Migrations

With the help of entity framework code, first database migrations create the database named Security in the SQL Server. Run the following command through the Visual Studio Package Manager Console to migrate your code into the SQL Server database.

Custom Authentication and Authorization in ASP.NET MVC (3)

After running the first command i.e. enabling migrations for your project, add seed data to Configuration.cs file of Migrations folder as shown below:

protected override void Seed(Security.DAL.DataContext context) { Role role1 = new Role { RoleName = "Admin" }; Role role2 = new Role { RoleName = "User" }; User user1 = new User { Username = "admin", Email = "[email protected]", FirstName = "Admin", Password = "123456", IsActive = true, CreateDate = DateTime.UtcNow, Roles = new List() }; User user2 = new User { Username = "user1", Email = "[email protected]", FirstName = "User1", Password = "123456", IsActive = true, CreateDate = DateTime.UtcNow, Roles = new List() }; user1.Roles.Add(role1); user2.Roles.Add(role2); context.Users.Add(user1); context.Users.Add(user2); }

When the above three commands are executed successfully, as shown above, the following database will be created in your SQL Server.

Custom Authentication and Authorization in ASP.NET MVC (4)

Solution Structure

Custom Authentication and Authorization in ASP.NET MVC (5)

Designing the View Model

Create a view model class for handling the login process as given below:

public class LoginViewModel { [Required] [Display(Name = "User name")] public string Username { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } 
 public class CustomPrincipalSerializeModel { public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string[] roles { get; set; } }

Forms Authentication Initialization

public class AccountController : Controller { DataContext Context = new DataContext(); // // GET: /Account/ public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(LoginViewModel model, string returnUrl = "") { if (ModelState.IsValid) { var user = Context.Users.Where(u => u.Username == model.Username && u.Password == model.Password).FirstOrDefault(); if (user != null) { var roles=user.Roles.Select(m => m.RoleName).ToArray(); CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel(); serializeModel.UserId = user.UserId; serializeModel.FirstName = user.FirstName; serializeModel.LastName = user.LastName; serializeModel.roles = roles; string userData = JsonConvert.SerializeObject(serializeModel); FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket( 1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(15), false, //pass here true, if you want to implement remember me functionality userData); string encTicket = FormsAuthentication.Encrypt(authTicket); HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); Response.Cookies.Add(faCookie); if(roles.Contains("Admin")) { return RedirectToAction("Index", "Admin"); } else if (roles.Contains("User")) { return RedirectToAction("Index", "User"); } else { return RedirectToAction("Index", "Home"); } } ModelState.AddModelError("", "Incorrect username and/or password"); } return View(model); } [AllowAnonymous] public ActionResult LogOut() { FormsAuthentication.SignOut(); return RedirectToAction("Login", "Account", null); } } 
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); Database.SetInitializer<DataContext>(new DataContextInitilizer()); } protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) { HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie != null) { FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); CustomPrincipalSerializeModel serializeModel = JsonConvert.DeserializeObject<CustomPrincipalSerializeModel>(authTicket.UserData); CustomPrincipal newUser = new CustomPrincipal(authTicket.Name); newUser.UserId = serializeModel.UserId; newUser.FirstName = serializeModel.FirstName; newUser.LastName = serializeModel.LastName; newUser.roles = serializeModel.roles; HttpContext.Current.User = newUser; } } }

Base Controller for Accessing Current User

Create a base controller for accessing your User data in your all controllers. Inherit, your all controller from this base controller to access user information from the UserContext.

public class BaseController : Controller { protected virtual new CustomPrincipal User { get { return HttpContext.User as CustomPrincipal; } } }
public class HomeController : BaseController { // // GET: /Home/ public ActionResult Index() { string FullName = User.FirstName + " " + User.LastName; return View(); } }

Base View Page for Accessing Current User

Create a base class for all your views for accessing your User data in your all views as shown below:

 public abstract class BaseViewPage : WebViewPage { public virtual new CustomPrincipal User { get { return base.User as CustomPrincipal; } } } public abstract class BaseViewPage<TModel> : WebViewPage<TModel> { public virtual new CustomPrincipal User { get { return base.User as CustomPrincipal; } } }

Register this class within the \Views\Web.config as the base class for all your views as given below:

<system.web.webPages.razor> <!--Other code has been removed for clarity--> <pages pageBaseType="Security.DAL.Security.BaseViewPage"> <namespaces> <!--Other code has been removed for clarity--> </namespaces> </pages> </system.web.webPages.razor>

Now you can access the authenticated user information on all your view in an easy and simple way as shown below in Admin View:

@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_AdminLayout.cshtml";}<h4>Welcome : @User.FirstName</h4><h1>Admin DashBoard</h1>

Login View

@model Security.Models.LoginViewModel@{ ViewBag.Title = "Index";}@using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>User Login</h4> <hr /> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.Username, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Username) @Html.ValidationMessageFor(model => model.Username) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.RememberMe, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.RememberMe) @Html.ValidationMessageFor(model => model.RememberMe) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Login" class="btn btn-default" /> </div> </div> </div>}

Applying CustomAuthorize Attribute

To make secure your admin or user pages, decorate your Admin and User controllers with CustomAuthorize attribute as defined above and specify the uses or roles to access admin and user pages.

[CustomAuthorize(Roles= "Admin")] // [CustomAuthorize(Users = "1")] public class AdminController : BaseController { // // GET: /Admin/ public ActionResult Index() { return View(); } }
 [CustomAuthorize(Roles= "User")] // [CustomAuthorize(Users = "1,2")] public class UserController : BaseController { // // GET: /User/ public ActionResult Index() { return View(); } }

You can also specify the Roles and Users within your web.config as a key to avoid hard code values for Users and Roles at the controller level.

<add key="RolesConfigKey" value="Admin"/> <add key="UsersConfigKey" value="2,3"/>

Use one of these keys within the CustomAuthorize attribute as shown below:

//[CustomAuthorize(RolesConfigKey = "RolesConfigKey")][CustomAuthorize(UsersConfigKey = "UsersConfigKey")] public class AdminController : BaseController { // // GET: /Admin/ public ActionResult Index() { return View(); } }
 [CustomAuthorize(RolesConfigKey = "RolesConfigKey")]// [CustomAuthorize(UsersConfigKey = "UsersConfigKey")] public class UserController : BaseController { // // GET: /User/ public ActionResult Index() { return View(); } }

Test your Application

When you run your application and will login into the application using user1, you will be redirected to User dashboard as shown below:

Custom Authentication and Authorization in ASP.NET MVC (6)

Custom Authentication and Authorization in ASP.NET MVC (7)

When the user tries to access unauthorized pages such as the Admin dashboard using the URL: http://localhost:11681/Admin, he will get the custom error page as shown below:

Custom Authentication and Authorization in ASP.NET MVC (8)

Summary

I hope you will enjoy the tips while implementing role-based or user-based security in your ASP.NET MVC application. I would like to have feedback from my blog readers. Your valuable feedback, questions, or comments about this article are always welcome. Enjoy Coding..!

For more knowledge of the core concepts of ASP.NET MVC, consider enrolling in our ASP.NET MVC Certification Course to get your hands on the best comprehensive training program.

Unlock the next level of MVC:

FAQs

Q1. What is custom authentication?

We use an authentication server to produce custom signed tokens when a user successfully signs in

Q2. What is custom authentication in asp net?

We can use the membership provider class which can check the user credentials (username & password) and the role provider class which is used to verify the user authorization based on his/her roles.

Q3. What is authenticate used for?

when the server needs to know exactly who is accessing their information or site.

Q4. What is custom authorization in ASP.NET MVC?

Custom Authorization is ASP.NET MVC refers to implementing custom logic that helps in determining if a user is authorized to access particular resources or not

Q5. How can I implement custom authentication in ASP.NET MVC?

To implement custom authentication in ASP.NET MVC, you need to create a custom authentication filter that will further perform logic to authenticate users.

Custom Authentication and Authorization in ASP.NET MVC (2024)
Top Articles
Droplet Plans To Disrupt Mobile Cash With No-Charges Payment App For iPhone | TechCrunch
While the 'Timeline Isn't Final,' Ethereum Could Implement The Merge on September 19 - YesMobile
Evil Dead Movies In Order & Timeline
Victor Spizzirri Linkedin
Wordscapes Level 6030
Air Canada bullish about its prospects as recovery gains steam
Exam With A Social Studies Section Crossword
Kobold Beast Tribe Guide and Rewards
Polyhaven Hdri
Cosentyx® 75 mg Injektionslösung in einer Fertigspritze - PatientenInfo-Service
Best Private Elementary Schools In Virginia
Gt Transfer Equivalency
litter - tłumaczenie słowa – słownik angielsko-polski Ling.pl
Unit 1 Lesson 5 Practice Problems Answer Key
Aspen.sprout Forum
The fabulous trio of the Miller sisters
Tcu Jaggaer
Why Is 365 Market Troy Mi On My Bank Statement
Ruse For Crashing Family Reunions Crossword
Aldi Bruce B Downs
Isaidup
Rochester Ny Missed Connections
Rubber Ducks Akron Score
Globle Answer March 1 2023
Netwerk van %naam%, analyse van %nb_relaties% relaties
Carroway Funeral Home Obituaries Lufkin
Duke University Transcript Request
Housing Intranet Unt
Suspect may have staked out Trump's golf course for 12 hours before the apparent assassination attempt
Exploring The Whimsical World Of JellybeansBrains Only
Covalen hiring Ai Annotator - Dutch , Finnish, Japanese , Polish , Swedish in Dublin, County Dublin, Ireland | LinkedIn
Tmka-19829
Msnl Seeds
Housing Intranet Unt
Craigslist Mexicali Cars And Trucks - By Owner
Verizon Outage Cuyahoga Falls Ohio
Bartow Qpublic
Craigslist Rooms For Rent In San Fernando Valley
Random Animal Hybrid Generator Wheel
Hanco*ck County Ms Busted Newspaper
Flappy Bird Cool Math Games
844 386 9815
Pixel Gun 3D Unblocked Games
Learn4Good Job Posting
Www Pig11 Net
Westport gun shops close after confusion over governor's 'essential' business list
Fresno Craglist
Read Love in Orbit - Chapter 2 - Page 974 | MangaBuddy
One Facing Life Maybe Crossword
Booked On The Bayou Houma 2023
Latest Posts
Article information

Author: Van Hayes

Last Updated:

Views: 6244

Rating: 4.6 / 5 (46 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Van Hayes

Birthday: 1994-06-07

Address: 2004 Kling Rapid, New Destiny, MT 64658-2367

Phone: +512425013758

Job: National Farming Director

Hobby: Reading, Polo, Genealogy, amateur radio, Scouting, Stand-up comedy, Cryptography

Introduction: My name is Van Hayes, I am a thankful, friendly, smiling, calm, powerful, fine, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.