Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you deal with authorisation on actions that return results other than ViewResult?

I am using a custom authorization filter on my ASP.NET MVC controllers that redirects the user to a url other than the login screen if they fail authorisation on a particular action.

This is ok for actions that return views, but many of my actions return other result types such as PartialResult or JsonResult.

My current filter looks like this:

<AuthorizeWithRedirect(Roles:="ServerAccess", Controller:="Home", Action:="Unauthorised")>

This indicates that if the user is not in the ServerAccess role then they should be redirected to /Home/Unauthorised/

I am curious how other people are handling this? This seems particularly problematic when you consider the number of actions that are intended to only be called by client-side script AJAX calls. How can the /Home/Unauthorised/ action know whether the caller was intended to receive a view, partialview, json, content, etc?

like image 698
Nick Avatar asked Sep 24 '09 15:09

Nick


People also ask

Can I return ActionResult Instead of view results?

First to Understand---ActionResult and ViewResult are basically a return type for an method(i.e Action in MVC). Second The Difference is --- ActionResult can return any type of Result Whereas ViewResult can return result type of View Only.

What is authentication and Authorization in ASP.NET MVC?

A user is authenticated by its identity and assigned roles to a user determine about authorization or permission to access resources. ASP.NET provides IPrincipal and IIdentity interfaces to represents the identity and role for a user.

What is action result () concrete class?

What is an ActionResult? ActionResult is an abstract class that represents the result of an action method. The class itself inherits from System. Object, and only adds one additional abstract method: ExecuteResult, which is an abstract method that the derived classes of ActionResult will implement themselves.


2 Answers

Use Request.IsAjaxRequest(), e.g.:

public sealed class AjaxAuthorizeAttribute : AuthorizeAttribute
{
    public AjaxAuthorizeAttribute() : base()
    {
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        // Extends the original Web.MVC.AuthorizeAttribute for Ajax calls.
        // Basically if the request is not authorized and the request is an AJAX Request.
        // then we simply set the stats Code to 403 and set an empty Result, in order to 
        // determine in Javascript if the AJAX call came back completed and valid.
        base.OnAuthorization(filterContext);
        if (filterContext.Result == null)
        {
            return;
        }
        else if (filterContext.Result.GetType() == typeof(HttpUnauthorizedResult) 
                 && filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new ContentResult();
            filterContext.HttpContext.Response.StatusCode = 403;
        }
    }
}

Note 403, not 401, since ASP.NET intercepts 401s and turns them into HTML error pages. It doesn't matter what the AJAX call expected to receive; it can still see the status code.

like image 146
Craig Stuntz Avatar answered Oct 20 '22 04:10

Craig Stuntz


I think you'll need to pass in that information with the redirection.

A couple ways you could handle this:

  • Consider making separate action methods for each type of response you need - UnauthorizedJson, UnauthorizedHtml, UnauthorizedEtc... that corresponded to the original action response type

  • Pass in the format information with the redirection by adding another parameter to the Unauthorized method and appending it to the URL in your filter

like image 34
womp Avatar answered Oct 20 '22 04:10

womp