Monday, September 21, 2015

Custom Authentication using IAuthenticationFilter


Requirement: Only validated users/Logged in users should be able to view application pages, others should be redirected to login screen.

Assuming you already have a login page and users are being validated against DB.

Step 1: Create a folder named "CustomAttributes" in the root of your MVC website.

Step 2: Create a class named "CustomUserAuthenticationAttribute" under the newly created folder.

Step 3: Inherit and implement the class using System.Web.Mvc.ActionFilterAttribute, IAuthenticationFilter

public class CustomUserAuthenticationAttribute : System.Web.Mvc.ActionFilterAttribute, IAuthenticationFilter
{
 //Implemention goes here
}

Step 4: Use following Namespaces:

using System.Web.Mvc;
using System.Web.Mvc.Filters;

Step 5: Create methods shown below:

     /// <summary>
        /// This is Called when a Controller/Action decorated with [CustomUserAuthentication] is executed.
        /// </summary>
        /// <param name="context">The context.</param>
        public void OnAuthentication(AuthenticationContext context)
        {
            //Get Logged in User info from Session
            var currentUserSessionInfo = Common.GetFromSession<UserSessionInfo>(Common.SessionKeys.UserSessionInfo);

            //Return unauthorized result if user info is null
            if (currentUserSessionInfo == null)
            {
                context.Result = new HttpUnauthorizedResult();
            }
            //If User is not logged in OR Branch Logged in is null, logout user and return unauthorized result 
            else if (!currentUserSessionInfo.IsUserLoggedIn || string.IsNullOrEmpty(currentUserSessionInfo.BranchLoggedIn))
            {
                var usr = currentUserSessionInfo.LoggedInUser;
                if (usr != null)
                {
                    usr.Logout();
                    usr.Dispose();
                }
                context.Result = new HttpUnauthorizedResult();
            }

        }


        /// <summary>
        /// This gets called after OnAuthentication has returned its result
        /// </summary>
        /// <param name="context">The context.</param>
        public void OnAuthenticationChallenge(AuthenticationChallengeContext context)
        {
            //If an unauthorizedResult is detected, redirect to login screen
            if (context.Result == null || context.Result is HttpUnauthorizedResult)
            {
                context.Result = new RedirectToRouteResult("Default",
                    new System.Web.Routing.RouteValueDictionary{
                        {"controller", "Account"},
                        {"action", "Login"},
                        {"returnUrl", context.HttpContext.Request.RawUrl}
                    });
            }
        }

Step 6: Now decorate a controller with [CustomUserAuthentication].

I wanted to allow only authenticated users to access my home page, my controller looked like this:

[CustomUserAuthentication]
    public class HomeController : BaseController
    {

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

    }

Every time home page is called, users are validated using IAuthenticationFilter. This prevents home page from any unauthenticated user's access. If I need more such pages, I just need to decorate the new page's controller/ action.

No comments:

Post a Comment