开发者

"cannot set status after HTTP headers" when overriding AuthorizeAttribute.AuthorizeCore

开发者 https://www.devze.com 2023-04-12 14:13 出处:网络
I\'m trying to implement custom basic authentication on specific controller of MVC 2 application. Specifically I inherited from AuthorizeAttribute and override AuthorizeCore() method:

I'm trying to implement custom basic authentication on specific controller of MVC 2 application. Specifically I inherited from AuthorizeAttribute and override AuthorizeCore() method:

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    if( doAuthorization() ) {
        return true;
    }
    // send HTTP 401
    HttpContext context = HttpContext.Current;
    context.Response.StatusCode = 401;
    context.Response.AddHeader( "WWW-Authenticate",
        String.Format("Basic realm=\"{0}\"", myRealm);
    context.Response.End();
    return false;
}

and marked the controller with my inherited attribute.

The whole thing works, but whenever AuthorizeCore returns false MVC continues processing the request and Application_Error() is invoked and I retrieve the following exception there:

Server cannot set status after HTTP headers have开发者_开发知识库 been sent.
at System.Web.HttpResponse.set_StatusCode(Int32 value)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

How do I make MVC stop processing the request and prevent that exception?


I ran into a similar problem (where I need to redirect) and the below fixed mine

  1. I used OnAuthorization override
  2. When I had to redirect did the below

    filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Redirect); filterContext.HttpContext.Response.Redirect(url, false);

The key was to populate filterContext.Result. If populated the MVC framework was not invoking the action method.


Please see answer here: Extend AuthorizeAttribute Override AuthorizeCore or OnAuthorization

You should not be setting headers and ending the response in AuthorizeCore, as its 'decision code'

Override OnAuthorization to add headers etc

EDIT: To prevent MVC continuing processing the request, FilterContext.Result in OnAuthorization needs to be set.

EDIT: You may end up getting a CustomError. If so add the following:

HttpContext.Response.TrySkipIisCustomErrors(true)
0

精彩评论

暂无评论...
验证码 换一张
取 消