How to create custom JsonAuthorize Attribute to se

2019-08-07 19:05发布

问题:

I was thinking how to correctly secure JsonResult action with custom attribute instead of doing kind of this on each action like saying here ASP.NET MVC JsonResult and AuthorizeAttribute

if (!User.Identity.IsAuthenticated)
    return Json("Need to login");

But the question is how could i create such attribute which would return Json. So i've started from that:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class JsonAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }
            IPrincipal user = httpContext.User;

            if (!user.Identity.IsAuthenticated)
            { 
               //? 
            }

            //Need to return json somehow ?
        }
    }

Bot how i may return json result from such attribute? any ideas?

回答1:

You can use an ActionFilterAttribute which allows you to return a result without using the httpcontext.response.write or anything.

public class JsonActionFilterAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        if (!HttpContext.Current.User.Identity.IsAuthenticated) {
            filterContext.Result = new JsonResult() { Data = "Need to login." };
        }
        base.OnActionExecuting(filterContext);
    }
}


回答2:

1 way is to override AuthorizeAttribute.HandleUnauthorizedRequest

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    throw new CustomUnauthorizedException();
}

... And then in your Global.asax:

protected void Application_Error(object sender, EventArgs e)
{
    Exception error = Server.GetLastError();
    if (error is CustomUnauthorizedException) {
        if (AjaxRequest(Request)) {
            ... return Json response.
        } else {
            ... redirect
        }
    }
}

So you can throw the exception anywhere in your codebase and you've centralized the handling of that exception in Global.asax



回答3:

Try this.. it works for me

 protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
 {
   dynamic ResponseObj = new JObject();
   ResponseObj.Message = "Authorization has been denied for this request.";
   string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(ResponseObj);
   actionContext.Response = new HttpResponseMessage
    {
      StatusCode = HttpStatusCode.Unauthorized,
      Content = new StringContent(jsonString, System.Text.Encoding.UTF8,"application/json")
     };
 }