Search code examples
c#asp.net-mvcasp.net-identityauthorize-attributeform-authentication

How to return to previous URL after login? (ajax)


So I have a MVC5 web application (it came with ASP.Identity framework) and I have this custom Authorize attribute.

public class FrontEndAuthorize : AuthorizeAttribute
{

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        dynamic user = (ClaimsPrincipal)httpContext.User;

        if (user.Identity.IsAuthenticated) {
            return true;
        }

        return false;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext context)
    {
        if (context.HttpContext.Request.IsAjaxRequest()) {
            dynamic urlHelper = new UrlHelper(context.RequestContext);
            context.HttpContext.Response.TrySkipIisCustomErrors = true;
            context.HttpContext.Response.StatusCode = 403;

            context.Result = new JsonResult {
                Data = new {
                    Error = "NotAuthorized",
                    LogOnUrl = urlHelper.Action("LogIn", "Account")
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        } else {
            base.HandleUnauthorizedRequest(context);
        }
    }
}

And I have some problem with ajax method. For example if I have Articles page warheat1990.com/articles/batman-arkham-knight-review with a button to submit comment.

[HttpPost]
[FrontEndAuthorize]
public ActionResult SubmitComment(string comment)
{
    //code here
    return Content("success");
}

And I have a script to call the method when user click the Submit Comment button.

$.ajax({
    url: '/Articles/SubmitComment/'
    type: 'POST'
    //rest of code here
})

When user click the Submit Comment button without LogIn first, the user will be redirected to LogIn page, however on LogIn success, user is taken back to Home page aka warheat1990.com instead of warheat1990.com/articles/batman-arkham-knight-review.

This is cause by SubmitComment method is called from ajax. So my question is what should I do to be able to redirect user to previous page on ajax call?


Solution

  • The basic idea is that your HandleUnauthorizedRequest method needs to provide a "return to" parameter to the page/controller handling the login. Instead of sending your user to just the login page:

    LogOnUrl = urlHelper.Action("LogIn", "Account")
    

    You would provide an additional returnUrl query param:

    // for your ajax
    LogOnUrl = urlHelper.Action("LogIn", "Account", new { returnUrl = context.HttpContext.Request.RawUrl })
    
    // for your non-ajax:
    context.Result = new RedirectToRouteResult(
                    new System.Web.Routing.RouteValueDictionary
                        {                     
                                { "controller", "Account" },
                                { "action", "Login" },
                                { "returnUrl", context.HttpContext.Request.RawUrl }
                        });
    

    The user would land on a page like:

    warheat1990.com/login?returnUrl=warheat1990.com%2Farticles%2Fbatman-arkham-knight-review
    

    If login succeeds, then you would parse the request for the query param returnUrl value (if it exists), and redirect the user to that location.