Search code examples
c#asp.netajaxauthorize-attributeauthorize

POSTing Ajax form using [Authorize] attribute after the user is logged out ASP.NET


Intro

I am building a WebApp for a client using ASP.NET MVC in C#.

I have an Ajax form within a modal window, that gets submitted when the user clicks a button.

The user has to be logged in, in order to be on this particular page and do this particular action - so I'm using the [Authorize] attribute for the necessary controller actions.

Let's say the controller action the form is POSTing to looks like this (psuedo-code, just an example):

[Authorize]
public ActionResult DoAjaxThings(string field, string anotherfield)
{
    // ... do things
    if (success)
    {
        return Json(new { success = true });
    }
    else
    {
        return Json(new { success = false, error = "Something went wrong" });
    }
}

As you can see I return a Json object back with a success property and an error if necessary.

This is then handled by the callback method in the page, and off it goes to show spinners and unicorns and other magic.

If successful, the modal is closed and a "success" message is shown.

If not successful and an error is returned, an error div is filled with the error message I send back. Sounds fairly straightforward?..


Scenario

Let's say the user's session token only lasts 15 minutes - and is sliding (each new request resets it (not necessarily vital to the question)). They're not using the "remember me" option.

If they've been idle/sitting on a page for more than the allotted time, then the token runs out.

Obviously, by this point their session token has expired, and they will need to log in again.

Usual behaviour would occur when navigating to [Authorize] controller actions: taking the user back to the Login page, with the ReturnUrl=xyz query string.


Imagine This

So, back to the modal's Ajax form.

User has been on the page for 15 minutes, and their token has now expired.

They click the button to perform the [Authorize]d action...

The the Action method is not executed, and the WebApp returns a redirect to the Login page.

But what is returned through this Ajax call is the ENTIRE Login page. And seeing as there is no success, the callback function receives the redirect, which squashes the Login page - all into this one little tiny div.

You don't need me to tell you that this looks fudging hideous.


Question

It is clear to see that WebApp realises the [Authorize] attribute and that the user is logged out.

I can't hit any breakpoints inside the Action, because the [Authorize] takes over and redirects automatically.

So, what I ask is this:

How can I bypass/overcome/solve this issue with the [Authorize] being triggered first and the Action code block not being executed?

Your kind suggestions, answers and general guidance are appreciated, as always.


Solution

  • You could remove the [Authorize] attribute, check the authorization in your controller method (if (User.Identity.IsAuthenticated)), and return a suitable error to the client if the user is not authorized.