Share via


Question about the [Authorize] attribute and Ajax/REST methods

Question

Tuesday, July 29, 2008 3:50 AM

Hi Folks,
    what's the best way to handle REST methods / Ajax calls using the Authorize method? Bascially, if you're not authorized, then i don't want to redirect to a login page. Alternatively, i might not even have a login route declared in the web.config for the forms section.

Of the top of my head, i was thinking of setting the loginUrl to (custom) 401 Unauthorised page? i would love it if the authorize attribute checked to see if the loginUrl is null or empty, and if so, redirect to a 401 :) that would be uber kewl.

All replies (12)

Wednesday, July 30, 2008 1:17 AM âś…Answered

Can you leave all your authentication alone but add this to each action (I guess an actionFilter would be the correct way to implement)?

if (!Request.IsAuthenticated && Request.IsMvcAjaxRequest) {
   Response.StatusCode = 401;
   return Content("");
}

 


Tuesday, July 29, 2008 10:36 PM

I'm having a look at the OnAuthorization(..) method in the AuthorizeAttribute class.

I'm wondering if it's possible to throw a

Response.Clear();
Response.StatusCode = 401;
Response.End;

.. or something like that, in this method if IsAuthenticated is false and there is no loginPage form. The downside with this, though .. is that it's tightly coupled to the forms authentication .. which means we can't do that :(

Anyone have any suggestions?


Wednesday, July 30, 2008 1:43 AM

The downside with this, though .. is that it's tightly coupled to the forms authentication .. which means we can't do that :(

What specifically is tightly coupled with forms auth?  We went to great lengths to make sure that [Authorize] isn't formsauth-specific.


Wednesday, July 30, 2008 1:50 AM

what does 'return Content(""); do ?

would i be better to replace that line with Response.End(); instead?

 I love your idea, though :) I'm not going to be using MVC ajax but just pure jQuery (at least until i know what all this new ajax helper stuff is doing) .. so i'll prolly mod that first line a bit.

edit:

What specifically is tightly coupled with forms auth?  We went to great lengths to make sure that [Authorize] isn't formsauth-specific.

Nothing :) I think you misread my post or more likely, i worded it badly. The current code is NOT tightly coupled .. but my personal idea's to mod it, would have been (which is a bad bad thing .. which is why i was hoping for a better suggestion .. and got it).


Wednesday, July 30, 2008 2:19 AM

I was assuming that you are inside a controller action.  return Content("") is an empty response body of type ContentType (just used it for the first time today).  Probably the same thing as (or at least very similar to) response.end()

The MVC Ajax stuff justs adds "__MVCAJAX=true" to the body of every form it submits.  I have actually used the Stephen Walther ContextActionInvoker http://weblogs.asp.net/stephenwalther/archive/2008/07/11/asp-net-mvc-tip-18-parameterize-the-http-context.aspx and added

values.Add("IsAjax", context.Request.Form["__MVCAJAX"]??"false");

into his customised InvokeAction.  A typical controller action of mine which cares about Ajax looks like

public ActionResult Create(bool IsAjax)
{
    if (IsAjax)
        return View("Create");
    else
        return View("Index", IndexViewData(0, true));
}

So, Ajax requests get a partial page rendering (Create.ascx) and non-Ajax requests get a full page (Index.aspx).  I guess that it would be pretty easy to come up with a similar scheme getting jquery  to add a field to every form and then sanitise (note: spelt with an 's' not a 'z') it using something like the Stephen Walther method.

Good luck


Wednesday, July 30, 2008 2:32 AM

sweet dude :) makes complete sense.

For me, i usually have certain controller methods that are (more or less) ajax specific. So it would be possible to call them via the browser by typing it in the url box but their main use would be for ajax calls. As such (read: having that ajax to method-action coupling) i can be direct in my decorating of specific methods with this ajaxauthorize attribute i can make up.

Levib, while I have your attention in this thread ... have you guys though about the use of the [Authorize] attribute + Ajax calls  ... and if so .. not necesarily MS Ajax or __MVCAjax?


Wednesday, July 30, 2008 3:06 AM

have you guys though about the use of the [Authorize] attribute + Ajax calls  ... and if so .. not necesarily MS Ajax or __MVCAjax?

Sorry, it's been a long day, so I'm a bit slow right now and don't really understand your question. :)  Are you asking for advice on making [Authorize] work on methods that tend to be called via AJAX requests?  There shouldn't be any real difference.  Or are you asking for an [AjaxOnly] attribute?  We have a work item for the latter.


Wednesday, July 30, 2008 3:44 AM

Are you asking for advice on making [Authorize] work on methods that tend to be called via AJAX requests?

Nope - because that would mean i would need to modify the current code base (which i would dl) from codeplex ... which means i'd have serious probs with future releases, etc. In my original post, i was eluding to doing this .. but was unhappy if this was the only way to do what i want.

Or are you asking for an [AjaxOnly] attribute?  We have a work item for the latter.

Yep! I was curious to see if you guys have thought about this and you said there's a work item, so you have :) In the mean time, i can create my own [AjaxOnly] attribute for authorization required for Ajax specific methods and later on replace it with the attrbute that's been added to the main codebase via you guys :)

 I'm assuming that when you suggested an [AjaxOnly] attribute, this will be for authorization for ajax methods (big assumption of my understanding your reply, above).

Thanks again Levib for taking the time to read this thread.


Wednesday, July 30, 2008 10:53 AM

I'm assuming that when you suggested an [AjaxOnly] attribute, this will be for authorization for ajax methods (big assumption of my understanding your reply, above).

Well, authorization is a funny word in this context.  An [AjaxOnly] attribute would not perform authorization in the typical sense since we're not making a security decision.  Right now I'm not even sure what such an attribute would do since it's not speced yet.


Wednesday, July 30, 2008 7:29 PM

Fair enough.

I was hoping that you guys might consider an [AuthorizeAjax] attribute (unless the AjaxOnly attrib will do that, when spec'd .. if that's it's intended purpose) ... which would redirect the user to a 401 if IsAuthenticated is false and the request is via ajax.


Wednesday, July 30, 2008 7:40 PM

Why not just stick both [Authorize] and [AjaxOnly] on the same action method?


Wednesday, July 30, 2008 8:17 PM

.. because [Authorize] _currently_ tries to bounce you to the login page (if using forms-auth). I was wanting to get it to 'throw' a 401 (for ajax only).

 so unless u the [Authorize] attribute can be smart enough to figure out that the method is also [AjaxOnly] ..... then we have a solution :) (btw: i do like your suggestion, btw).