Authentication and Authorization in MVC Application


In any kind of software application, Authentication and Authorization are taken very seriously. In this blog, we will see how can we apply authorization in an MVC application.
By default, all Controllers and Actions in an MVC application are accessible by anonymous users. The Authorize attribute handles authorization for a logged-in user in MVC application.
First, we will understand the Authentication and Authorization mechanism in a web application.

What is Authentication?

Authentication is the process to validate the passed credentials for an application. If a passed credential is ok then the user is authenticated in the application.

What is Authorization?

Once the Authentication process is a success, then Authorization took place as the next step. Authorization is the process to specify access to a particular resource.

Create an MVC Application and apply Authorization

Now, we will come to Visual Studio to create an MVC application.
I have created 2 controllers in my MVC application to demonstrate this blog.
Account Controller and Admin Controller.

Our Popular Blog -

Authorize Attribute in MVC

In an ASP.Net MVC application, each and every request is connected with the controller and action pair.
If you want to secure admin pages then you have to use [Authorize] attribute to controllers related to admin pages.
Authorize attribute tells HTTP request that on what Controller or action method a logged-in user is authorized to access. Authorize attribute can be implemented by simply decorating a controller or action with [Authorize].

Below is the syntax to use the Authorize attribute with an action method in MVC.

        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

Instead of applying the Authorize attribute on individual action, we can apply the Authorize attribute on the MVC controller itself.

    [Authorize]
    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }
        }


The authorize attribute supports a few parameters as well.
For example, if you want to allow a controller or action to be accessible only by a user if his/her role is Admin then use below syntax.

    [Authorize(Roles= "admin")]
    public class AdminController : Controller
    {
       
        public ActionResult Dashboard()
        {
            return View();
        }
       }

We can also provide a specific user name to the Authorize attribute using below syntax.

   [Authorize(Roles= "admin", , Users = "user1")]
    public class AdminController : Controller
    {
       
        public ActionResult Dashboard()
        {
            return View();
        }
         }


Account Controller file -
Write the below code in the Account controller.

    public class AccountController : Controller
    {
        CommonLibrary library = new CommonLibrary();

        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Login(UserEntity userEntity)
        {
            DataSet ds = library.UserDetails(userEntity, "login");
            if (ds != null)
            {
                if (ds.Tables[0].Rows.Count > 0)
                {
                    Session["email"] = ds.Tables[0].Rows[0]["email"];
                    Session["name"] = ds.Tables[0].Rows[0]["first_name"];
                    Session["role"] = ds.Tables[0].Rows[0]["role"];

                    FormsAuthentication.SetAuthCookie(userEntity.Email, false);

                    var authTicket = new FormsAuthenticationTicket(1, userEntity.Email, DateTime.Now, DateTime.Now.AddMinutes(20), false, userEntity.Role.ToString());
                    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                    HttpContext.Response.Cookies.Add(authCookie);
                    return RedirectToAction("Dashboard", "Admin");
                }
                ViewData["Alert"] = "Login";
                return View();
            }
            else
            {
                ViewData["Alert"] = "Login";
                return View();
            }
        }

       
        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();
            Session.Clear();
            Session.Abandon();
            return RedirectToAction("Index", "Home");
        }
    }

Add below namespace in Account Controller -

using System.Web.Security;

FormsAuthentication classes and related properties come under System.Web.Security namespace.

Next, Create a class file to call data library function.
CommonLibrary.cs

public DataSet UserDetails(UserEntity user, string call)
        {
           
            try
            {
                SqlParameter[] parameters = {
                    new SqlParameter("@call",call),
                    new SqlParameter("@email",user.Email),
                    new SqlParameter("@password",user.Password),
                };
                ds = CommonDataLibrary.ExecuteDataSet("SP_Get_Data_ById", parameters);
            }
            catch (Exception ex)
            {

                throw;
            }

            return ds;
        }

Write database-related code in ComonDataLibrary.cs file.

ComonDataLibrary.cs


private static string DBConnectionString;

        public static string ConnectionStringName
        {
            get
            {
                return _connStringName;
            }
            set
            {
                _connStringName = value;
            }
        }

        private static void GetConnectionstring()
        {
            ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"];
            if ((connectionString == null) || (connectionString.ConnectionString.Trim() == String.Empty))
            {
                throw new ProviderException("Connection string cannot be blank.");
            }

            DBConnectionString = connectionString.ConnectionString;
        }


public static DataSet ExecuteDataSet( string storedProcedure, SqlParameter[] parameters)
        {
            if (string.IsNullOrEmpty(DBConnectionString))
                GetConnectionstring();

            SqlConnection sqlConnection = new SqlConnection(DBConnectionString);
            SqlCommand sqlCommand = new SqlCommand(storedProcedure, sqlConnection);
            sqlCommand.CommandType = CommandType.StoredProcedure;

            sqlCommand.Parameters.AddRange(parameters);
            DataSet ds = new DataSet();

            try
            {
                sqlConnection.Open();
                SqlDataAdapter sda = new SqlDataAdapter(sqlCommand);
                sda.Fill(ds);
                return ds;

            }
            catch (SqlException ex)
            {

                return null;

            }
            finally
            {
                DisposeSQLConnection(sqlConnection);
            }

        }

public static void DisposeSQLConnection(SqlConnection con)
        {
            if (con.State == ConnectionState.Open)
            {
                con.Close();
                con.Dispose();
            }
        }


Now, create a controller and add action with the name Dashboard. Dashboard action can be accessible only if the user is authorized. I have decorated the Admin controller with the Authorize attribute, it means all action inside the Admin controller can be accessible only if the user is authorized.

Admin Controller -

    [Authorize]
    public class AdminController : Controller
    {

        /// <summary>
        /// Dashboard to show total story category wise, total user role wise, total views weekly highlight
        /// </summary>
        /// <returns></returns>
        public ActionResult Dashboard()
        {
            return View();
        }
      }

Add a method in Global.asax file to set the authorization for a logged-in user.

Why Global.asax file?

Global.asax file responds to the HTTP request as soon as the application gets loaded. It is an optional file. The method written in this file gets execute before executing any action method in a controller in the MVC application.

Global.asax.cs file -

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

Finally, add an authentication tag in the web.config file. This tag should be within <system.web>
We.config

<authentication mode="Forms">
      <forms loginUrl="account/Login"></forms>
    </authentication>


Summary :
Authorization gives a security level to the MVC application.
To apply Authorization in MVC controller or action, create an MVC application.
Add authorization method in Global.asax file.
Decorate the desired controller or action with [Authorize] attribute.
If you want to apply Authorization to a particular action then decorate that action with Authorize attribute.
If you want to authorize all action within a controller, then apply Authorize attribute on the controller itself.

If you like this blog, share this on social media. To give any feedback please write down in the comment section.

You may like other blogs -

Interview Questions and Answers Series -

MVC Interview Questions and Answers
Web API interview questions and answers

Comments

Popular