How to return a custom view OR a JSON when the Authorization fail, instead of showing a username and password dialog

StackOverflow https://stackoverflow.com/questions/20940145

Question

I am working on an asp.net mvc 4 web application , and i wrote the following custom authorization class:-

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

    public class CheckUserPermissionsAttribute : AuthorizeAttribute
    {

        public string Model { get; set; }
        public string Action { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsAuthenticated)
                return false;
            //code goes here
            if (!repository.can(ADusername, Model, value)) // implement this method based on your tables and logic
            {

                return false;
                //base.HandleUnauthorizedRequest(filterContext);
            }
            return true;

           // base.OnAuthorization(filterContext);
        }
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {

                var viewResult = new JsonResult();
                viewResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
                viewResult.Data = (new { IsSuccess = "Unauthorized", description = "Sorry, you do not have the required permission to perform this action." });
                filterContext.Result = viewResult;

            }
            else
            {
                var viewResult = new ViewResult();

                viewResult.ViewName = "~/Views/Errors/_Unauthorized.cshtml";

                filterContext.Result = viewResult;
            }

            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

but the only problem i am facing now is that if the authorization fail then the user will be prompted to enter username and password, although i have override the HandleUnauthorizedRequest to return a view or JSON based on if the request is AJAX or not. so can you advice why the user is being prompted to enter his username and password when the authorization fail, instead of receiving the _unauthorized view or the JSON containing an error message

Was it helpful?

Solution

but the only problem i am facing now is that if the authorization fail then the user will be prompted to enter username and password, although i have override the HandleUnauthorizedRequest to return a view or JSON based on if the request is AJAX or not.

That's because you are absolutely always hitting the following line in your HandleUnauthorizedRequest method:

base.HandleUnauthorizedRequest(filterContext);

You know what this line do? It calls the base method. You know what the base method do? It returns 401 status code. You know what happens when 401 status response code is returned in an ASP.NET application in which you are using Forms Authentication? You get the login page.

So yeah, if you are using AJAX or something and intend to be returning some JSON or something make sure that the base stuff is never called. By the way in your else condition you seem to be attempting to render some ~/Views/Errors/_Unauthorized.cshtml view which obviously is useless once again because you are also calling the base method which will simply redirect to the login page.

I think that at this stage of my answer you already know what to do: get rid of this last line of your HandleUnauthorizedRequest method in which you are throwing all your efforts into the trash by calling the base method.

And if you want to do things properly and return 401 status code and not get the login page but instead return some custom JSON you could use the SuppressFormsAuthenticationRedirect property on the Response object. And if you are using some legacy version of the .NET framework which doesn't have this property you might find the following blog post useful in which Phil Haack explains how to handle this case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top