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?
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.
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 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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With