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
- I used OnAuthorization override
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)
精彩评论