13

I have a method decorated with two custom ActionFilterAttribute.

[RequiresAuthentication(Order = 1)]
[ToonAction(Order = 2)]
public ActionResult Browse(...

RequiresAuthentication attribute is coming from this article

Inside RequiresAuthentication, on it's OnActionExecuting I do:

 filterContext.HttpContext.Response.Redirect(loginUrl, true);

The line is get executed, and the arguments are all as expected. The problem is that after executing the line above, I get next attribute (ActionFilterAttribute) executed, as if redirect didn't work, it just continues executing the request, instead of simply redirecting browser.

Question: what else do I need to do to make the request handler

This is a complete method:

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        //redirect if not authenticated
        var identity = filterContext.HttpContext.User.Identity;
        if (!identity.IsAuthenticated) {
            //use the current url for the redirect
            string redirectOnSuccess = filterContext.HttpContext.Request.Url.PathAndQuery;

            //send them off to the login page
            string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);
            string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
            // filterContext.Result = new HttpUnauthorizedResult();
            // filterContext.HttpContext.Response.StatusCode = 0x191;
        }
    }
THX-1138
  • 21,316
  • 26
  • 96
  • 160

5 Answers5

27

You want to set the Result on the filterContext to a RedirectResult, not do a redirect on the response.

 filterContext.Result = new RedirectResult { Url = loginUrl };

EDIT: As @Hunter Daley suggests a better mechanism would be to use the AuthorizeAttribute instead if it works for you. If you do have authentication/authorization scenarios that the AuthorizeAttribute doesn't work for, it would probably be better to derive your custom attribute from it instead of the more generic ActionFilterAttribute. In any event, the correct technique is to set the Result rather than interact with the Response directly. You might want to look at the actual AuthorizeAttribute source at http://www.codeplex.com/aspnet for ideas.

I've got a sample of custom authorization code on my blog, http://farm-fresh-code.blogspot.com, too.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • This turned out to be the answer I needed -- I was doing a redirect on the Response, and for months I could not figure out why I was getting "Cannot set cookie" errors. – Matt Sherman Aug 12 '10 at 03:02
2

try adding the [Authorize] attribute to your Action methods instead

hunter
  • 62,308
  • 19
  • 113
  • 113
2

Add

filterContext.HttpContext.Response.Clear();

at first and this at End :

filterContext.HttpContext.Response.End();

Hope this helps.

ali62b
  • 5,363
  • 4
  • 22
  • 25
  • 2
    Didn't help: filterContext.HttpContext.Response.Redirect(loginUrl, true); already does it inside. – THX-1138 Feb 02 '10 at 20:48
0

you can use return RedirectToAction("Index", "Home/Login", new {area = "", returnURL = Request.Url.AbsolutePath}); to stop the current processing, redirect to the desired (login) page and quit the action. the area route property is needed to get out of the current area if you are in any.

d.popov
  • 4,175
  • 1
  • 36
  • 47
0

Add this code before you redirect the page.

filterContext.ExceptionHandled = true;
Chan
  • 914
  • 9
  • 25