×

iFour Logo

A Detailed Guide on Custom Authentication and Authorization in ASP.NET MVC

Kapil Panchal - July 15, 2021

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

  • play
  • pause
  • pause
A Detailed Guide on Custom Authentication and Authorization in ASP.NET MVC

Introduction


In this blog, we'll show you how to make your authentication application. Authentication and authorization are indispensable aspects for any website project to grant users access based on their roles, as you may know. To build custom authentication, we utilize the membership provider class to check user credentials (username and password) and the role provider class to validate user authorization based on roles.

Our authentication system's scenario is as follows:

  1. After the user enters his or her credentials (Login and Password), we must use the ValidateUser method from our custom membership provider class.

  2. We need to choose a bespoke membership provider that will be utilized. We must make this change within the Web.config file.

  3. When a user is successfully authenticated, the Authorize Attribute filter is automatically invoked to determine whether the user has access to the requested resource, and the role provider is the class that is responsible for doing so depending on the user role.

  4. Note that we must also define a role provider in the Web.config file.

Create Your MVC application


First, open the Visual Studio and select File -> New Project

This will pop up the New Project window. Select ASP.NET Web Application(.NET Framework) and then click OK.

NewASP.NETWebApplication

Figure: Create New ASP.NET Web Application

Now, give the name of the project like CustomAuthenticationMVC, and select the appropriate location where you want to save your project and then click on the create button to create your project.

choosethepathandcreateaproject

Figure : Name the project, choose the path and create a project

Then, choose MVC and click on create to add the project.

SelectMVC

Figure : Select MVC project template and create the project

We will establish a database using the entity framework (Code first approach) once our project is created.

SQL Database part


Entity framework takes a variety of approaches to map databases, including database first, model first, and code first.

To construct our database, simply follow the steps below. First and foremost, we'll establish a folder called Data Access.

To accomplish this, right-click on the project name in Solution Explorer >> Add >> New Folder.

Then we'll add the User and Role entities.

Example

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

namespace CustomAuthenticationMVC.DataAccess
{
    public class User
    {
        public int UserId { get; set; }
        public string Username { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public bool IsActive { get; set; }
        public Guid ActivationCode { get; set; }
        public virtual ICollection Roles { get; set; }

    }
}

Example

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

namespace CustomAuthenticationMVC.DataAccess
{
    public class Role
    {
        public int RoleId { get; set; }
        public string RoleName { get; set; }
        public virtual ICollection Users { get; set; }
    }
}

As the last step, we're going to add our AuthenticationDB context, which will allow us to access database data. Normally, the context class derives from the dbcontext class.

Example

using CustomAuthenticationMVC.DataAccess;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Configuration;

namespace CustomAuthenticationMVC.DataAccess
{
    public class AuthenticationDB : DbContext
    {
        public AuthenticationDB()
            :base("AuthenticationDB")
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity()
                .HasMany(u => u.Roles)
                .WithMany(r => r.Users)
                .Map(m =>
                {
                    m.ToTable("UserRoles");
                    m.MapLeftKey("UserId");
                    m.MapRightKey("RoleId");
                });
        }

        public DbSet Users { get; set; }
        public DbSet Roles { get; set; }
    }
}

Note

Make sure you've included your database's connection string in the Web.config file.


            
            

Now enter the following command into the Package Manager console.

 

Enable-migrations


After performing above aspects, now we're ready to start building our database. Executes the commands in the order listed below.

add-migration "initial_migration"

update-database –verbose

CustomAuthenticationDB

Figure: Create a CustomAuthenticationDB by enabling migration

As you can see, all of the tables have been successfully added.

Implementing Membership Provider and Role Provider


Let's get started with the custom MemberShip Provider.

The first step is to construct the CustomMembership class, which should inherit from MembershipProvider.

After that, we'll override the following methods based on our requirements:

  • ValidateUser is a function that takes two parameters: username and password, and checks whether the user exists or not.
  • The GetUser method is in charge of returning user info based on the username input.
  • GetUserNameByEmail takes an email address as an input and returns a username.

Example

using CustomAuthenticationMVC.DataAccess;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace CustomAuthenticationMVC.CustomAuthentication
{
    public class CustomMembership : MembershipProvider
    {


        
        public override bool ValidateUser(string username, string password)
        {
            if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                return false;
            }

            using (AuthenticationDB dbContext = new AuthenticationDB())
            {
                var user = (from us in dbContext.Users
                            where string.Compare(username, us.Username, StringComparison.OrdinalIgnoreCase) == 0
                            && string.Compare(password, us.Password, StringComparison.OrdinalIgnoreCase) == 0
                            && us.IsActive == true
                            select us).FirstOrDefault();

                return (user != null) ? true : false;
            }
        }
password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            using (AuthenticationDB dbContext = new AuthenticationDB())
            {
                var user = (from us in dbContext.Users
                            where string.Compare(username, us.Username, StringComparison.OrdinalIgnoreCase) == 0
                            select us).FirstOrDefault();

                if(user == null)
                {
                    return null;
                }
                var selectedUser = new CustomMembershipUser(user);

                return selectedUser;
            }
        }

        public override string GetUserNameByEmail(string email)
        {
            using (AuthenticationDB dbContext = new DataAccess.AuthenticationDB())
            {
                string username = (from u in dbContext.Users
                                   where string.Compare(email, u.Email) == 0
                                   select u.Username).FirstOrDefault();

                return !string.IsNullOrEmpty(username) ? username : string.Empty;
            }
        }

        

        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool EnablePasswordReset
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override bool EnablePasswordRetrieval
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override int MaxInvalidPasswordAttempts
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override int MinRequiredPasswordLength
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override int PasswordAttemptWindow
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override string PasswordStrengthRegularExpression
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override bool RequiresUniqueEmail
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }


    }
}


As you can see, MembershipProvider offers a lot of methods like Create User, ChangePassword, GetPassword, and so on, but we only need ValidateUser, GetUser, and GetUserNameByEmail.

Here we can point out that the GetUser method makes use of the CustomMemberShipUser class to retrieve only the information we require about the user.

Example

using System;
using CustomAuthenticationMVC.DataAccess;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace CustomAuthenticationMVC.CustomAuthentication
{
    public class CustomMembershipUser : MembershipUser
    {
        #region User Properties

        public int UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public ICollection Roles { get; set; }

        #endregion

        public CustomMembershipUser(User user):base("CustomMembership", user.Username, user.UserId, user.Email, string.Empty, string.Empty, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now)
        {
            UserId = user.UserId;
            FirstName = user.FirstName;
            LastName = user.LastName;
            Roles = user.Roles;
        }
    }
}

The second step, as previously said, is to include our customerMembership in the Web.config file. Now we'll update the web.config file and add the following snippet of code.


            
            
            
  


We'll now use Custom Role Provider to implement it.

In this case, we'll construct a CustomRole class that inherits from RoleProvider and then override the GetRolesForUser and IsUserInRole methods.

Example

using CustomAuthenticationMVC.DataAccess;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace CustomAuthenticationMVC.CustomAuthentication
{
    public class CustomRole : RoleProvider
    {
        public override bool IsUserInRole(string username, string roleName)
        {
            var userRoles = GetRolesForUser(username);
            return userRoles.Contains(roleName);
        }
        public override string[] GetRolesForUser(string username)
        {
            if (!HttpContext.Current.User.Identity.IsAuthenticated)
            {
                return null;
            }

            var userRoles = new string[] { };

            using (AuthenticationDB dbContext = new AuthenticationDB())
            {
                var selectedUser = (from us in dbContext.Users.Include("Roles")
                                    where string.Compare(us.Username, username, StringComparison.OrdinalIgnoreCase) == 0
                                    select us).FirstOrDefault();

                
                if(selectedUser != null)
                {
                    userRoles = new[] { selectedUser.Roles.Select(r=>r.RoleName).ToString() };
                }

                return userRoles.ToArray();
            }


        }



      

        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            throw new NotImplementedException();
        }

        public override string[] GetUsersInRole(string roleName)
        {
            throw new NotImplementedException();
        }


        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }

      
    }
}

Note that the GetRolesForUser method takes a username as a parameter and returns all roles associated with that username. The IsUserInRole method takes two parameters: username and rolename, and verifies whether the user has a role that grants him access to the desired resource.

Want to Hire Trusted .Net Development Company ?

After that, add the following code snippet to the web.config file.


            
            
            
  


Custom principals and identities are now being implemented. We have a user property that contains basic user data by default to receive user information from HTTP requests. User information is accessed deeply using the IPrincipal interface. In reality, the Identity property of this interface encompasses all user data.

As previously stated, the user property only contains basic user information; however, the goal is to expand this property to include more useful data.

Now, we'll develop the CustomPrincipal class, which will inherit from the IPrincipal interface.

Example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;

namespace CustomAuthenticationMVC.CustomAuthentication
{
    public class CustomPrincipal : IPrincipal
    {
        #region Identity Properties

        public int UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string[] Roles { get; set; }
        #endregion

        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)
        {
            Identity = new GenericIdentity(username);
        }
    }
}

Note

We'll add the following code snippet within Global.asax to replace the default user property from HttpContext.

Example

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies["Cookie1"];
    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        var serializeModel = JsonConvert.DeserializeObject(authTicket.UserData);

        CustomPrincipal principal = new CustomPrincipal(authTicket.Name);

        principal.UserId = serializeModel.UserId;
        principal.FirstName = serializeModel.FirstName;
        principal.LastName = serializeModel.LastName;
        principal.Roles = serializeModel.RoleName.ToArray();

        HttpContext.Current.User = principal;
    }

}

Create a controller


Following the implementation of Custom Membership Provider and Custom Role Provider, I think it is now time to design an Account Controller with all of the required actions to assist us in authenticating users.

We're going to make a controller now. Right-click the controllers folder> > Add >> Controller>> MVC 5 Controller - Empty>> Add. Name the controller “AccountController” in the following dialogue, then click on the Add to add controller successfully.

MVC5Controller-Empty

Figure: Choose “MVC5 Controller-Empty” from the above controller

AccountController

Figure: Choose “MVC5 Controller-Empty” from the above controller

Example

using CustomAuthenticationMVC.CustomAuthentication;
using CustomAuthenticationMVC.DataAccess;
using CustomAuthenticationMVC.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace CustomAuthenticationMVC.Controllers
{
    [AllowAnonymous]
    public class AccountController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult Login(string ReturnUrl = "")
        {
            if (User.Identity.IsAuthenticated)
            {
                return LogOut();
            }
            ViewBag.ReturnUrl = ReturnUrl;
            return View();
        }

        [HttpPost]
        public ActionResult Login(LoginView loginView, string ReturnUrl = "")
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(loginView.UserName, loginView.Password))
                {
                    var user = (CustomMembershipUser)Membership.GetUser(loginView.UserName, false);
                    if (user != null)
                    {
                        CustomSerializeModel userModel = new Models.CustomSerializeModel()
                        {
                            UserId = user.UserId,
                            FirstName = user.FirstName,
                            LastName = user.LastName,
                            RoleName = user.Roles.Select(r => r.RoleName).ToList()
                        };

                        string userData = JsonConvert.SerializeObject(userModel);
                        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket
                            (
                            1, loginView.UserName, DateTime.Now, DateTime.Now.AddMinutes(15), false, userData
                            );

                        string enTicket = FormsAuthentication.Encrypt(authTicket);
                        HttpCookie faCookie = new HttpCookie("Cookie1", enTicket);
                        Response.Cookies.Add(faCookie);
                    }

                    if (Url.IsLocalUrl(ReturnUrl))
                    {
                        return Redirect(ReturnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index");
                    }
                }
            }
            ModelState.AddModelError("", "Something Wrong : Username or Password invalid ^_^ ");
            return View(loginView);
        }

        [HttpGet]
        public ActionResult Registration()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Registration(RegistrationView registrationView)
        {
            bool statusRegistration = false;
            string messageRegistration = string.Empty;

            if (ModelState.IsValid)
            {
                
                string userName = Membership.GetUserNameByEmail(registrationView.Email);
                if (!string.IsNullOrEmpty(userName))
                {
                    ModelState.AddModelError("Warning Email", "Sorry: Email already Exists");
                    return View(registrationView);
                }

                //Save User Data 
                using (AuthenticationDB dbContext = new AuthenticationDB())
                {
                    var user = new User()
                    {
                        Username = registrationView.Username,
                        FirstName = registrationView.FirstName,
                        LastName = registrationView.LastName,
                        Email = registrationView.Email,
                        Password = registrationView.Password,
                        ActivationCode = Guid.NewGuid(),
                    };

                    dbContext.Users.Add(user);
                    dbContext.SaveChanges();
                }

               
                VerificationEmail(registrationView.Email, registrationView.ActivationCode.ToString());
                messageRegistration = "Your account has been created successfully. ^_^";
                statusRegistration = true;
            }
            else
            {
                messageRegistration = "Something Wrong!";
            }
            ViewBag.Message = messageRegistration;
            ViewBag.Status = statusRegistration;

            return View(registrationView);
        }

        [HttpGet]
        public ActionResult ActivationAccount(string id)
        {
            bool statusAccount = false;
            using (AuthenticationDB dbContext = new DataAccess.AuthenticationDB())
            {
                var userAccount = dbContext.Users.Where(u => u.ActivationCode.ToString().Equals(id)).FirstOrDefault();

                if (userAccount != null)
                {
                    userAccount.IsActive = true;
                    dbContext.SaveChanges();
                    statusAccount = true;
                }
                else
                {
                    ViewBag.Message = "Something Wrong !!";
                }

            }
            ViewBag.Status = statusAccount;
            return View();
        }

        public ActionResult LogOut()
        {
            HttpCookie cookie = new HttpCookie("Cookie1", "");
            cookie.Expires = DateTime.Now.AddYears(-1);
            Response.Cookies.Add(cookie);

            FormsAuthentication.SignOut();
            return RedirectToAction("Login", "Account", null);
        }

        [NonAction]
        public void VerificationEmail(string email, string activationCode)
        {
            var url = string.Format("/Account/ActivationAccount/{0}", activationCode);
            var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, url);

            var fromEmail = new MailAddress("mehdi.rami2012@gmail.com", "Activation Account - AKKA");
            var toEmail = new MailAddress(email);

            var fromEmailPassword = "******************";
            string subject = "Activation Account !";

            string body = "
 Please click on the following link in order to activate your account" + "
 Activation Account ! ";

            var smtp = new SmtpClient
            {
                Host = "smtp.gmail.com",
                Port = 587,
                EnableSsl = true,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential(fromEmail.Address, fromEmailPassword)
            };

            using (var message = new MailMessage(fromEmail, toEmail)
            {
                Subject = subject,
                Body = body,
                IsBodyHtml = true

            })

                smtp.Send(message);

        }
    }
}

Account controller has three major actions, as you can see above.

  • Check to see if the person who is going to create a new account has already been created. To do so, we'll use the CustomMembershipProvider's GetUserNameByEmail function.
  • After that, we'll save user information.
  • We must activate the user account by sending a verification email to the user, informing him that he must activate his account by clicking on the activation link.
  • Login action takes a loginView model as a parameter, which has a username and password properties, and then uses the ValidateUser method from custom Membership to check user credentials. If user validation is true, the GetUser function is used to retrieve user data.
  • Following that, we'll create an authentication ticket that will be encrypted using the term FormsAuthentication. Finally, we'll encrypt (authTicket) and create a faCookie object with our ticket's encrypted value as the value.
  • The registration action is used to create a new account for a user. This action will do three things on a deep level:
  • The LogOut action allows the user to log out of his or her session, as the name suggests.

We must now add account views for login, registration, and activation.

Example


@model CustomAuthenticationMVC.Models.LoginView

@{
    ViewBag.Title = "Login";
}

Login

@using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) { @Html.AntiForgeryToken()

LoginView


@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.RememberMe, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.RememberMe) @Html.ValidationMessageFor(model => model.RememberMe, "", new { @class = "text-danger" })
}
@Html.ActionLink("Back to List", "Index")

Example


@model CustomAuthenticationMVC.Models.RegistrationView

@{
    ViewBag.Title = "Registration";
}

Registration

@if (ViewBag.Status != null && Convert.ToBoolean(ViewBag.Status)) { if (ViewBag.Message != null) {
Success! @ViewBag.Message
} } else { using (Html.BeginForm()) { @Html.AntiForgeryToken()

RegistrationView


@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) @Html.ValidationMessage("ErrorEmail", new { @class = "text-danger" })
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
if(ViewBag.Message != null) {
Error! @ViewBag.Message
} } }
@Html.ActionLink("Login", "Login")
@section Scripts{ }

Example


@{
    ViewBag.Title = "Activation Account ^_^";
}

Activation Account

@if(ViewBag.Status != null && Convert.ToBoolean(ViewBag.Status)) {
Success! Your account has been activated successfully.
} else {
Error!@ViewBag.Message
}

Authorization filter


We'll implement a custom authorization filter in this section.

We want to create a filter that denies access to the user controller if the connected user does not have a user role.

Let's take it step by step.

First, make a CustomAuthorizeAttribute class that is derived from AuthorizeAttribute.

Example

using CustomAuthenticationMVC.CustomAuthentication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace CustomAuthenticationMVC.CustomAuthentication
{
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected virtual CustomPrincipal CurrentUser
        {
            get { return HttpContext.Current.User as CustomPrincipal; }
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return ((CurrentUser != null && !CurrentUser.IsInRole(Roles)) || CurrentUser == null) ? false : true;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            RedirectToRouteResult routeData = null;

            if(CurrentUser == null)
            {
                routeData = new RedirectToRouteResult
                    (new System.Web.Routing.RouteValueDictionary
                    (new
                    {
                        controller = "Account",
                        action = "Login",
                    }
                    ));
            }
            else
            {
                routeData = new RedirectToRouteResult
                (new System.Web.Routing.RouteValueDictionary
                 (new
                 {
                     controller = "Error",
                     action = "AccessDenied"
                 }
                 ));
            }

            filterContext.Result = routeData;
        }

    }
}

Example

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

namespace CustomAuthenticationMVC.Controllers
{
    [CustomAuthorize(Roles = "User")]
    public class UserController : Controller
    {
        
        // GET: User
        public ActionResult Index()
        {
            return View();
        }
    }
}

When a user is successfully authenticated but does not have a user role, we should alert him that his or her access is denied. In the HandleUnauthorizedRequest method, we did something like this.

Example

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

namespace CustomAuthenticationMVC.Controllers
{
    public class ErrorController : Controller
    {
        // GET: Error
        public ActionResult AccessDenied()
        {
            return View();
        }
    }
}

Example


@{
    ViewBag.Title = "AccessDenied";
}

AccessDenied

Conclusion


In this blog, we have learned about authentication and authorization in Asp.Net MVC using an example. It will assist you comprehending the importance of validation for any website.

A Detailed Guide on Custom Authentication and Authorization in ASP.NET MVC Table of Content 1. Introduction 2. Create Your MVC application 3. SQL Database part 4. Enable-migrations 5. Implementing Membership Provider and Role Provider 6. Create a controller 7. Authorization filter 8. Conclusion Introduction In this blog, we'll show you how to make your authentication application. Authentication and authorization are indispensable aspects for any website project to grant users access based on their roles, as you may know. To build custom authentication, we utilize the membership provider class to check user credentials (username and password) and the role provider class to validate user authorization based on roles. Our authentication system's scenario is as follows: After the user enters his or her credentials (Login and Password), we must use the ValidateUser method from our custom membership provider class. We need to choose a bespoke membership provider that will be utilized. We must make this change within the Web.config file. When a user is successfully authenticated, the Authorize Attribute filter is automatically invoked to determine whether the user has access to the requested resource, and the role provider is the class that is responsible for doing so depending on the user role. Note that we must also define a role provider in the Web.config file. Create Your MVC application First, open the Visual Studio and select File -> New Project This will pop up the New Project window. Select ASP.NET Web Application(.NET Framework) and then click OK. Figure: Create New ASP.NET Web Application Now, give the name of the project like CustomAuthenticationMVC, and select the appropriate location where you want to save your project and then click on the create button to create your project. Figure : Name the project, choose the path and create a project Then, choose MVC and click on create to add the project. Figure : Select MVC project template and create the project We will establish a database using the entity framework (Code first approach) once our project is created. SQL Database part Entity framework takes a variety of approaches to map databases, including database first, model first, and code first. To construct our database, simply follow the steps below. First and foremost, we'll establish a folder called Data Access. To accomplish this, right-click on the project name in Solution Explorer >> Add >> New Folder. Then we'll add the User and Role entities. Example using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace CustomAuthenticationMVC.DataAccess { public class User { public int UserId { get; set; } public string Username { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string Password { get; set; } public bool IsActive { get; set; } public Guid ActivationCode { get; set; } public virtual ICollection Roles { get; set; } } } Example using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace CustomAuthenticationMVC.DataAccess { public class Role { public int RoleId { get; set; } public string RoleName { get; set; } public virtual ICollection Users { get; set; } } } As the last step, we're going to add our AuthenticationDB context, which will allow us to access database data. Normally, the context class derives from the dbcontext class. Example using CustomAuthenticationMVC.DataAccess; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Configuration; namespace CustomAuthenticationMVC.DataAccess { public class AuthenticationDB : DbContext { public AuthenticationDB() :base("AuthenticationDB") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .HasMany(u => u.Roles) .WithMany(r => r.Users) .Map(m => { m.ToTable("UserRoles"); m.MapLeftKey("UserId"); m.MapRightKey("RoleId"); }); } public DbSet Users { get; set; } public DbSet Roles { get; set; } } } Note Make sure you've included your database's connection string in the Web.config file. Now enter the following command into the Package Manager console.   Read More: Generate Thumbnail Using Asp.net Mvc Enable-migrations After performing above aspects, now we're ready to start building our database. Executes the commands in the order listed below. add-migration "initial_migration" update-database –verbose Figure: Create a CustomAuthenticationDB by enabling migration As you can see, all of the tables have been successfully added. Implementing Membership Provider and Role Provider Let's get started with the custom MemberShip Provider. The first step is to construct the CustomMembership class, which should inherit from MembershipProvider. After that, we'll override the following methods based on our requirements: ValidateUser is a function that takes two parameters: username and password, and checks whether the user exists or not. The GetUser method is in charge of returning user info based on the username input. GetUserNameByEmail takes an email address as an input and returns a username. Example using CustomAuthenticationMVC.DataAccess; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; namespace CustomAuthenticationMVC.CustomAuthentication { public class CustomMembership : MembershipProvider { public override bool ValidateUser(string username, string password) { if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { return false; } using (AuthenticationDB dbContext = new AuthenticationDB()) { var user = (from us in dbContext.Users where string.Compare(username, us.Username, StringComparison.OrdinalIgnoreCase) == 0 && string.Compare(password, us.Password, StringComparison.OrdinalIgnoreCase) == 0 && us.IsActive == true select us).FirstOrDefault(); return (user != null) ? true : false; } } password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new NotImplementedException(); } public override MembershipUser GetUser(string username, bool userIsOnline) { using (AuthenticationDB dbContext = new AuthenticationDB()) { var user = (from us in dbContext.Users where string.Compare(username, us.Username, StringComparison.OrdinalIgnoreCase) == 0 select us).FirstOrDefault(); if(user == null) { return null; } var selectedUser = new CustomMembershipUser(user); return selectedUser; } } public override string GetUserNameByEmail(string email) { using (AuthenticationDB dbContext = new DataAccess.AuthenticationDB()) { string username = (from u in dbContext.Users where string.Compare(email, u.Email) == 0 select u.Username).FirstOrDefault(); return !string.IsNullOrEmpty(username) ? username : string.Empty; } } public override string ApplicationName { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override bool EnablePasswordReset { get { throw new NotImplementedException(); } } public override bool EnablePasswordRetrieval { get { throw new NotImplementedException(); } } public override int MaxInvalidPasswordAttempts { get { throw new NotImplementedException(); } } public override int MinRequiredNonAlphanumericCharacters { get { throw new NotImplementedException(); } } public override int MinRequiredPasswordLength { get { throw new NotImplementedException(); } } public override int PasswordAttemptWindow { get { throw new NotImplementedException(); } } public override MembershipPasswordFormat PasswordFormat { get { throw new NotImplementedException(); } } public override string PasswordStrengthRegularExpression { get { throw new NotImplementedException(); } } public override bool RequiresQuestionAndAnswer { get { throw new NotImplementedException(); } } public override bool RequiresUniqueEmail { get { throw new NotImplementedException(); } } public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); } public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new NotImplementedException(); } public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new NotImplementedException(); } public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); } public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); } public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); } public override int GetNumberOfUsersOnline() { throw new NotImplementedException(); } public override string GetPassword(string username, string answer) { throw new NotImplementedException(); } public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { throw new NotImplementedException(); } public override string ResetPassword(string username, string answer) { throw new NotImplementedException(); } public override bool UnlockUser(string userName) { throw new NotImplementedException(); } public override void UpdateUser(MembershipUser user) { throw new NotImplementedException(); } } } As you can see, MembershipProvider offers a lot of methods like Create User, ChangePassword, GetPassword, and so on, but we only need ValidateUser, GetUser, and GetUserNameByEmail. Here we can point out that the GetUser method makes use of the CustomMemberShipUser class to retrieve only the information we require about the user. Example using System; using CustomAuthenticationMVC.DataAccess; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; namespace CustomAuthenticationMVC.CustomAuthentication { public class CustomMembershipUser : MembershipUser { #region User Properties public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public ICollection Roles { get; set; } #endregion public CustomMembershipUser(User user):base("CustomMembership", user.Username, user.UserId, user.Email, string.Empty, string.Empty, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now) { UserId = user.UserId; FirstName = user.FirstName; LastName = user.LastName; Roles = user.Roles; } } } The second step, as previously said, is to include our customerMembership in the Web.config file. Now we'll update the web.config file and add the following snippet of code. We'll now use Custom Role Provider to implement it. In this case, we'll construct a CustomRole class that inherits from RoleProvider and then override the GetRolesForUser and IsUserInRole methods. Example using CustomAuthenticationMVC.DataAccess; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; namespace CustomAuthenticationMVC.CustomAuthentication { public class CustomRole : RoleProvider { public override bool IsUserInRole(string username, string roleName) { var userRoles = GetRolesForUser(username); return userRoles.Contains(roleName); } public override string[] GetRolesForUser(string username) { if (!HttpContext.Current.User.Identity.IsAuthenticated) { return null; } var userRoles = new string[] { }; using (AuthenticationDB dbContext = new AuthenticationDB()) { var selectedUser = (from us in dbContext.Users.Include("Roles") where string.Compare(us.Username, username, StringComparison.OrdinalIgnoreCase) == 0 select us).FirstOrDefault(); if(selectedUser != null) { userRoles = new[] { selectedUser.Roles.Select(r=>r.RoleName).ToString() }; } return userRoles.ToArray(); } } public override string ApplicationName { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override void AddUsersToRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); } public override void CreateRole(string roleName) { throw new NotImplementedException(); } public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { throw new NotImplementedException(); } public override string[] FindUsersInRole(string roleName, string usernameToMatch) { throw new NotImplementedException(); } public override string[] GetAllRoles() { throw new NotImplementedException(); } public override string[] GetUsersInRole(string roleName) { throw new NotImplementedException(); } public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); } public override bool RoleExists(string roleName) { throw new NotImplementedException(); } } } Note that the GetRolesForUser method takes a username as a parameter and returns all roles associated with that username. The IsUserInRole method takes two parameters: username and rolename, and verifies whether the user has a role that grants him access to the desired resource. Want to Hire Trusted .Net Development Company ? CONTACT US After that, add the following code snippet to the web.config file. Custom principals and identities are now being implemented. We have a user property that contains basic user data by default to receive user information from HTTP requests. User information is accessed deeply using the IPrincipal interface. In reality, the Identity property of this interface encompasses all user data. As previously stated, the user property only contains basic user information; however, the goal is to expand this property to include more useful data. Now, we'll develop the CustomPrincipal class, which will inherit from the IPrincipal interface. Example using System; using System.Collections.Generic; using System.Linq; using System.Security.Principal; using System.Web; namespace CustomAuthenticationMVC.CustomAuthentication { public class CustomPrincipal : IPrincipal { #region Identity Properties public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string[] Roles { get; set; } #endregion 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) { Identity = new GenericIdentity(username); } } } Note We'll add the following code snippet within Global.asax to replace the default user property from HttpContext. Example protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) { HttpCookie authCookie = Request.Cookies["Cookie1"]; if (authCookie != null) { FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); var serializeModel = JsonConvert.DeserializeObject(authTicket.UserData); CustomPrincipal principal = new CustomPrincipal(authTicket.Name); principal.UserId = serializeModel.UserId; principal.FirstName = serializeModel.FirstName; principal.LastName = serializeModel.LastName; principal.Roles = serializeModel.RoleName.ToArray(); HttpContext.Current.User = principal; } } Create a controller Following the implementation of Custom Membership Provider and Custom Role Provider, I think it is now time to design an Account Controller with all of the required actions to assist us in authenticating users. We're going to make a controller now. Right-click the controllers folder> > Add >> Controller>> MVC 5 Controller - Empty>> Add. Name the controller “AccountController” in the following dialogue, then click on the Add to add controller successfully. Figure: Choose “MVC5 Controller-Empty” from the above controller Figure: Choose “MVC5 Controller-Empty” from the above controller Example using CustomAuthenticationMVC.CustomAuthentication; using CustomAuthenticationMVC.DataAccess; using CustomAuthenticationMVC.Models; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Mail; using System.Web; using System.Web.Mvc; using System.Web.Security; namespace CustomAuthenticationMVC.Controllers { [AllowAnonymous] public class AccountController : Controller { public ActionResult Index() { return View(); } [HttpGet] public ActionResult Login(string ReturnUrl = "") { if (User.Identity.IsAuthenticated) { return LogOut(); } ViewBag.ReturnUrl = ReturnUrl; return View(); } [HttpPost] public ActionResult Login(LoginView loginView, string ReturnUrl = "") { if (ModelState.IsValid) { if (Membership.ValidateUser(loginView.UserName, loginView.Password)) { var user = (CustomMembershipUser)Membership.GetUser(loginView.UserName, false); if (user != null) { CustomSerializeModel userModel = new Models.CustomSerializeModel() { UserId = user.UserId, FirstName = user.FirstName, LastName = user.LastName, RoleName = user.Roles.Select(r => r.RoleName).ToList() }; string userData = JsonConvert.SerializeObject(userModel); FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket ( 1, loginView.UserName, DateTime.Now, DateTime.Now.AddMinutes(15), false, userData ); string enTicket = FormsAuthentication.Encrypt(authTicket); HttpCookie faCookie = new HttpCookie("Cookie1", enTicket); Response.Cookies.Add(faCookie); } if (Url.IsLocalUrl(ReturnUrl)) { return Redirect(ReturnUrl); } else { return RedirectToAction("Index"); } } } ModelState.AddModelError("", "Something Wrong : Username or Password invalid ^_^ "); return View(loginView); } [HttpGet] public ActionResult Registration() { return View(); } [HttpPost] public ActionResult Registration(RegistrationView registrationView) { bool statusRegistration = false; string messageRegistration = string.Empty; if (ModelState.IsValid) { string userName = Membership.GetUserNameByEmail(registrationView.Email); if (!string.IsNullOrEmpty(userName)) { ModelState.AddModelError("Warning Email", "Sorry: Email already Exists"); return View(registrationView); } //Save User Data using (AuthenticationDB dbContext = new AuthenticationDB()) { var user = new User() { Username = registrationView.Username, FirstName = registrationView.FirstName, LastName = registrationView.LastName, Email = registrationView.Email, Password = registrationView.Password, ActivationCode = Guid.NewGuid(), }; dbContext.Users.Add(user); dbContext.SaveChanges(); } VerificationEmail(registrationView.Email, registrationView.ActivationCode.ToString()); messageRegistration = "Your account has been created successfully. ^_^"; statusRegistration = true; } else { messageRegistration = "Something Wrong!"; } ViewBag.Message = messageRegistration; ViewBag.Status = statusRegistration; return View(registrationView); } [HttpGet] public ActionResult ActivationAccount(string id) { bool statusAccount = false; using (AuthenticationDB dbContext = new DataAccess.AuthenticationDB()) { var userAccount = dbContext.Users.Where(u => u.ActivationCode.ToString().Equals(id)).FirstOrDefault(); if (userAccount != null) { userAccount.IsActive = true; dbContext.SaveChanges(); statusAccount = true; } else { ViewBag.Message = "Something Wrong !!"; } } ViewBag.Status = statusAccount; return View(); } public ActionResult LogOut() { HttpCookie cookie = new HttpCookie("Cookie1", ""); cookie.Expires = DateTime.Now.AddYears(-1); Response.Cookies.Add(cookie); FormsAuthentication.SignOut(); return RedirectToAction("Login", "Account", null); } [NonAction] public void VerificationEmail(string email, string activationCode) { var url = string.Format("/Account/ActivationAccount/{0}", activationCode); var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, url); var fromEmail = new MailAddress("mehdi.rami2012@gmail.com", "Activation Account - AKKA"); var toEmail = new MailAddress(email); var fromEmailPassword = "******************"; string subject = "Activation Account !"; string body = " Please click on the following link in order to activate your account" + " Activation Account ! "; var smtp = new SmtpClient { Host = "smtp.gmail.com", Port = 587, EnableSsl = true, DeliveryMethod = SmtpDeliveryMethod.Network, UseDefaultCredentials = false, Credentials = new NetworkCredential(fromEmail.Address, fromEmailPassword) }; using (var message = new MailMessage(fromEmail, toEmail) { Subject = subject, Body = body, IsBodyHtml = true }) smtp.Send(message); } } } Account controller has three major actions, as you can see above. Check to see if the person who is going to create a new account has already been created. To do so, we'll use the CustomMembershipProvider's GetUserNameByEmail function. After that, we'll save user information. We must activate the user account by sending a verification email to the user, informing him that he must activate his account by clicking on the activation link. Login action takes a loginView model as a parameter, which has a username and password properties, and then uses the ValidateUser method from custom Membership to check user credentials. If user validation is true, the GetUser function is used to retrieve user data. Following that, we'll create an authentication ticket that will be encrypted using the term FormsAuthentication. Finally, we'll encrypt (authTicket) and create a faCookie object with our ticket's encrypted value as the value. The registration action is used to create a new account for a user. This action will do three things on a deep level: The LogOut action allows the user to log out of his or her session, as the name suggests. We must now add account views for login, registration, and activation. Example @model CustomAuthenticationMVC.Models.LoginView @{ ViewBag.Title = "Login"; }Login @using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) { @Html.AntiForgeryToken() LoginView @Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.RememberMe, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.RememberMe) @Html.ValidationMessageFor(model => model.RememberMe, "", new { @class = "text-danger" }) } @Html.ActionLink("Back to List", "Index") Example @model CustomAuthenticationMVC.Models.RegistrationView @{ ViewBag.Title = "Registration"; }Registration @if (ViewBag.Status != null && Convert.ToBoolean(ViewBag.Status)) { if (ViewBag.Message != null) { Success! @ViewBag.Message } } else { using (Html.BeginForm()) { @Html.AntiForgeryToken() RegistrationView @Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) @Html.ValidationMessage("ErrorEmail", new { @class = "text-danger" }) @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" }) if(ViewBag.Message != null) { Error! @ViewBag.Message } } } @Html.ActionLink("Login", "Login") @section Scripts{ } Example @{ ViewBag.Title = "Activation Account ^_^"; }Activation Account @if(ViewBag.Status != null && Convert.ToBoolean(ViewBag.Status)) { Success! Your account has been activated successfully. } else { Error!@ViewBag.Message } Authorization filter We'll implement a custom authorization filter in this section. We want to create a filter that denies access to the user controller if the connected user does not have a user role. Let's take it step by step. First, make a CustomAuthorizeAttribute class that is derived from AuthorizeAttribute. Example using CustomAuthenticationMVC.CustomAuthentication; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace CustomAuthenticationMVC.CustomAuthentication { public class CustomAuthorizeAttribute : AuthorizeAttribute { protected virtual CustomPrincipal CurrentUser { get { return HttpContext.Current.User as CustomPrincipal; } } protected override bool AuthorizeCore(HttpContextBase httpContext) { return ((CurrentUser != null && !CurrentUser.IsInRole(Roles)) || CurrentUser == null) ? false : true; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { RedirectToRouteResult routeData = null; if(CurrentUser == null) { routeData = new RedirectToRouteResult (new System.Web.Routing.RouteValueDictionary (new { controller = "Account", action = "Login", } )); } else { routeData = new RedirectToRouteResult (new System.Web.Routing.RouteValueDictionary (new { controller = "Error", action = "AccessDenied" } )); } filterContext.Result = routeData; } } } Example using CustomAuthenticationMVC.CustomAuthentication; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace CustomAuthenticationMVC.Controllers { [CustomAuthorize(Roles = "User")] public class UserController : Controller { // GET: User public ActionResult Index() { return View(); } } } When a user is successfully authenticated but does not have a user role, we should alert him that his or her access is denied. In the HandleUnauthorizedRequest method, we did something like this. Example using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace CustomAuthenticationMVC.Controllers { public class ErrorController : Controller { // GET: Error public ActionResult AccessDenied() { return View(); } } } Example @{ ViewBag.Title = "AccessDenied"; }AccessDenied Conclusion In this blog, we have learned about authentication and authorization in Asp.Net MVC using an example. It will assist you comprehending the importance of validation for any website.

Build Your Agile Team

Enter your e-mail address Please enter valid e-mail

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 

Blog Our insights

Power Apps vs Power Automate: When to Use What?
Power Apps vs Power Automate: When to Use What?

I often see people asking questions like “Is Power App the same as Power Automate?”. “Are they interchangeable or have their own purpose?”. We first need to clear up this confusion...

Azure DevOps Pipeline Deployment for Competitive Business: The Winning Formula
Azure DevOps Pipeline Deployment for Competitive Business: The Winning Formula

We always hear about how important it is to be competitive and stand out in the market. But as an entrepreneur, how would you truly set your business apart? Is there any way to do...

React 18 Vs React 19: Key Differences To Know For 2024
React 18 Vs React 19: Key Differences To Know For 2024

Ever wondered how a simple technology can spark a revolution in the IT business? Just look at React.js - a leading Front-end JS library released in 2013, has made it possible. Praised for its seamless features, React.js has altered the way of bespoke app development with its latest versions released periodically. React.js is known for building interactive user interfaces and has been evolving rapidly to meet the demands of modern web development. Thus, businesses lean to hire dedicated React.js developers for their projects. React.js 19 is the latest version released and people are loving its amazing features impelling them for its adoption.