2015-08-04 4 views
2

В нашем проекте asp.net MVC 4, мы используем AuthorizeAttribute для осуществления контроля доступа, наш код, как этогоasp.net MVC запрос 4 конца в AuthorizeAttribute

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (IsValid()) 
     { 
      //do something 
     } 
     else 
     { 
      httpContext.Response.Redirect("~/Common/NoAuthorize", true); 
     } 
    } 
    protected bool IsValid() 
    { 
     //custom authentication logic 
     return true; 
    } 
} 

MVC Controller помеченного MyAuthorizeAttribute .The проблемы является когда пользователь недействителен, он должен немедленно перенаправить на страницу NoAuthorize. Но я выяснил, что он все равно будет запускать код в MVC Controller. После этого работает Redirect.

Я пытаюсь добавить httpContext.Response.End() и HttpContext.Current.Response.End(). Ни один из них не работает. Так как я могу сделать перенаправление сразу без запуска кода в Controller?

ответ

2

AuthorizeCore должно возвращать значение bool. Вы не переадресовываете этот метод. Вы должны изменить маршрут из метода HandleUnauthorizedRequest

protected override bool AuthorizeCore(HttpContextBase httpContext) 
{ 
    if (IsValid()) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

protected bool IsValid() 
{ 
    //custom authentication logic 
    return true; 
} 

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { 

    filterContext.Result = new RedirectToRouteResult(
           new RouteValueDictionary 
           { 
            { "action", "ActionName" }, 
            { "controller", "ControllerName" } 
           }); 
} 
+0

Спасибо Ваш ответ простой way.I найти что-то проще просто now.If '' AuthorizeCore' возвращения false', код в определенном действии 'Controller' также не будет запущен. – Xingxing

0

Вы можете исключить исключение.

protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (IsValid()) 
     { 
      //do something 
     } 
     else 
     { 
      // You can throw any exception even custom. 
      throw new AuthenticationException("User must be logged in to access this page."); 
     } 
    } 

Это зависит от того, как вы обрабатываете исключение в своем приложении. Я выполнил ниже метод в Global.asax.cs. Внутри этого метода я проверяю, не является ли это HttpException, и если оно AuthenticationException, то перенаправляйте его на соответствующее действие ErrorController, в этом случае на метод Forbidden.

protected void Application_Error(object sender, EventArgs e) 
    { 
     var ex = Server.GetLastError(); 

     if (ex is HttpException) 
     { 
      var httpEx = ex as HttpException; 
      statusCode = httpEx.GetHttpCode(); 

      switch (httpEx.GetHttpCode()) 
      { 
       case 400: 
        action = "BadRequest"; 
        break; 

       case 401: 
        action = "Unauthorized"; 
        break; 

       case 403: 
        action = "Forbidden"; 
        break; 

       case 404: 
        action = "PageNotFound"; 
        break; 

       case 500: 
        action = "CustomError"; 
        break; 

       default: 
        action = "CustomError"; 
        break; 
      } 
     } 
     else if (ex is AuthenticationException) 
     { 
      action = "Forbidden"; 
      statusCode = 403; 
     } 

     httpContext.ClearError(); 
     httpContext.Response.Clear(); 
     httpContext.Response.StatusCode = statusCode; 
     httpContext.Response.TrySkipIisCustomErrors = true; 
     routeData.Values["controller"] = "Error"; 
     routeData.Values["action"] = action; 

     controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction); 
     ((IController) controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData)); 
    } 

ErrorControllerForbidden() действие будет перенаправлять на соответствующую страницу, как показано ниже:

[ExcludeFromCodeCoverage] 
    [AllowAnonymous] 
    public ActionResult Forbidden() 
    { 
     Response.StatusCode = (int)HttpStatusCode.Forbidden; 

     var model = (ViewData.Model as HandleErrorInfo); 
     string returnUrl = string.Empty; 

     if (model != null) 
     { 
      returnUrl = Url.Action(model.ActionName, model.ControllerName); 
     } 

     return RedirectToAction("Login", "Account", new { returnUrl = returnUrl, name = "" }); 
    } 
Смежные вопросы