Justin Helgerson
Justin Helgerson

Reputation: 25521

Authorize attribute is letting ActionResult code execute

I have a custom attribute that I am using for Ajax requests to prevent the default FormsAuthentication workflow from happening (since it doesn't make sense for an Ajax request).

This is the custom authorize attribute:

public class AjaxAuthorize : AuthorizeAttribute {
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
        UrlHelper urlHelper;

        if (filterContext.HttpContext.Request.IsAjaxRequest()) {
            urlHelper = new UrlHelper(filterContext.RequestContext);

            filterContext.HttpContext.Response.StatusCode = 401;
            //Don't let IIS7 be mean.
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            //Return JSON which tells the client where the login page exists if the user wants to authenticate.
            filterContext.HttpContext.Response.Write(new JavaScriptSerializer().Serialize(
                new {
                    LoginUrl = string.Format("{0}?ReturnURL={1}", FormsAuthentication.LoginUrl, urlHelper.Encode(filterContext.HttpContext.Request.Url.PathAndQuery))
                }
            ));
            filterContext.HttpContext.Response.End();
        } else {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

I have my ActionResult decorated with the custom authorize attribute like so:

[HttpPut]
[ValidateInput(false)]
[AjaxAuthorize]
public ActionResult Comment(string id, string comment) {
    //stuff happens here.
}

An exception is thrown inside of my action result because I try to access information about a user that would only exist if you are logged in. But, I don't understand why this code is even being executed because I have my authorization attribute protecting the action.

Upvotes: 1

Views: 961

Answers (3)

Justin Helgerson
Justin Helgerson

Reputation: 25521

I ended up returning an HTTP 418 (I have been wanting to use this for awhile) so that the Forms Authentication module didn't intercept the request. Then in my script I look for that status code and handle it as an unauthorized request and do the proper redirect.

Upvotes: 1

STO
STO

Reputation: 10648

protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
{
    // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs. 
    filterContext.Result = new HttpUnauthorizedResult();
} 

This is default implementation of HandleUnauthorizedRequest. Probably you need to assign your custom ActionResult that contains JSON you need and valid status code. I'm not sure direct processing request object from HTTP context would work.

Upvotes: 1

AndreCruz
AndreCruz

Reputation: 663

Try calling base.HandleUnauthorizedRequest(filterContext); inside the IF block. Or just remove the ELSE block and always call base.HandleUnauthorizedRequest(filterContext);.

Upvotes: 0

Related Questions