Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpPost to ReturnURL after redirect

I am writing an ASP.NET MVC 2.0 application which requires users to log in before placing a bid on an item. I am using an actionfilter to ensure that the user is logged in and, if not, send them to a login page and set the return url. Below is the code i use in my action filter.

if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
    filterContext.Result = new RedirectResult(String.Concat("~/Account/LogOn","?ReturnUrl=",filterContext.HttpContext.Request.RawUrl));
    return;
}

In my logon controller I validate the users credentials then sign them in and redirect to the return url

FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
    return Redirect(returnUrl);
}

My problem is that this will always use a Get (HttpGet) request whereas my original submission was a post (HttpPost) and should always be a post. Can anyone suggest a way of passing this URL including the HttpMethod or any workaround to ensure that the correct HttpMethod is used?

like image 651
JP. Avatar asked May 30 '10 19:05

JP.


2 Answers

There's no easy way to do this. What I would recommend you is to redirect the unauthenticated users to the login page not when posting to some URL but when requesting the form that will POST to the authenticated URL.

If you know that the form you are presenting to an unauthenticated user will POST to an authenticated part of the site, well, don't present him the form. When this form is requested simply redirect to the login page for authentication and once authenticated redirect to the original form. This way you will ensure that only authenticated users will POST to the protected resource.

As far as automated POST requests are concerned (bots, web services, ...) returning a simple 401 status code to requests that do not provide credentials should be more than sufficient.

like image 177
Darin Dimitrov Avatar answered Oct 04 '22 00:10

Darin Dimitrov


I think I get why you want the authentication to only be on the bid POST action. A bid requires login, but any non-logged in user can see the auction page. Just like ebay/amazon etc. Everything is visible until you require payment or action based on a user.

You could change your attribute to instead return the Request.UrlReferrer to the login page if the Request.RequestType is a POST. Then they would be redirected to the auction page and can click bid again once they are logged in. You could even pass along a certain field, say amount, with the UrlReferrer so that you could re-populate the amount field once they land on the auction page. You could get that field from the Request.Form collection.

// in usage...    
[RequireLogin(AdditionalFields="amount,someotherfield")]
[HttpPost]
public ActionResult Bid(.....)

// the attribute 
class RequireLoginAttribute : ActionFilterAttribute
{
    public string AdditionalFields { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var returnUrl = filterContext.HttpContext.Request.RawUrl;
            if (filterContext.HttpContext.Request.RequestType == "POST")
            {
                returnUrl = filterContext.HttpContext.Request.UrlReferrer.PathAndQuery;
                // look for FORM values in request to append to the returnUrl
                // this can be helpful for a good user experience (remembering checkboxes/text fields etc)
            }

            filterContext.Result = new RedirectResult(String.Concat("~/Account/LogOn", "?ReturnUrl=", returnUrl));
            return;
        }
        base.OnActionExecuting(filterContext);
    }
}
like image 22
Jab Avatar answered Oct 04 '22 01:10

Jab