2010-04-05 51 views
44

[Authorize]屬性自定義403錯誤頁面是好的,方便的MS發明了,我希望它能夠解決我現在如何使授權屬性返回而不是重定向到登錄頁面

更具體的問題:

在當前客戶端未通過身份驗證 - [Authorize]從受保護的動作重定向到登錄頁面,登錄成功後 - 爲用戶帶來回,這是件好事。

但噹噹前客戶端已經認證但不授權運行的具體行動 - 所有我需要的是隻顯示我的一般403頁。

是否有可能無需控制器的身體內移動授權邏輯?

更新: 我需要的應該是語義上的行爲等於這個草圖:

public ActionResult DoWork() 
{ 
    if (!NotAuthorized()) 
    { 
     // this should be not redirect, but forwarding 
     return RedirectToAction("403");   
    } 

    return View(); 
} 

如此 - 應該沒有任何重定向和URL應該保持不變,但網頁的內容應與403頁

更新置換的2:我實現了這樣素描:

[HandleError] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 

    [CustomActionFilter] 
    public ActionResult About() 
    { 
     return View(); 
    } 

    public ActionResult Error_403() 
    { 
     return Content("403"); 
    } 
} 

public class CustomActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     filterContext.Result = new ContentResult { Content = "403" }; 
    } 
} 

並不能得到如何正確地轉發執行,以HomeController.Action_403(),所以它顯示403

更新3

filterContext.Result = new ViewResult() { ViewName = "Error_403" }; 

所以這是如何呈現的具體答案查看模板...但仍然不知道如何運行另一個控制器 - 無論如何,這是足夠好的解決方案。

+0

@casperOne:憑啥你添加註釋,因爲它是從我的人??? – zerkms 2010-10-19 22:29:27

+0

側面的評論妨礙了代碼的可讀性。將其放置在上方可防止滾動條出現,並且只是清理過程的一部分。 – casperOne 2010-10-20 16:27:16

+0

@casperOne:我是白癡,我需要眼鏡,對不起;-( – zerkms 2010-10-20 23:27:44

回答

30

您應該能夠創建自己的類,從AuthorizeAttribute派生並重寫AuthorizeCore方法,以提供所需的授權機制,這樣就可以通過使用屬性,而不是將其移動到適用於您的自定義授權碼控制器。

如果您需要對授權進行更細粒度的控制,那麼我建議您創建IActionFilter接口的實現(在屬性上,然後將該屬性應用於您的方法)。這將允許您在呼叫到達控制器之前攔截呼叫,並在您的控制器方法被調用之前提供之前的替代動作

這是由IActionFilter接口上實現OnActionExecuting method實現。如果你的邏輯判斷,你不應該撥打電話到控制器的一切,你要提供一個ActionResult要代爲處理,那麼你會在ActionExecutingContext實例傳遞到方法設置Result property。通過這樣做,ActionResult被處理,而不是去控制器方法得到ActionResult

如果你想返回403錯誤代碼,那麼你就不能使用ContentResult類。你必須創建自己的類,從ActionResult派生並重寫ExecuteResult方法來設置StatusCode propertyHttpResponseBase到403,就像這樣:

internal class Http403Result : ActionResult 
{ 
    public override void ExecuteResult(ControllerContext context) 
    { 
     // Set the response code to 403. 
     context.HttpContext.Response.StatusCode = 403; 
    } 
} 

public class CustomActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     filterContext.Result = new Http403Result(); 
    } 
} 

當然,你可以概括Http403Result類取一個構造函數它將接受你想要返回的狀態碼,但這個概念保持不變。

+0

幾乎我需要的,但AuthorizeCore返回布爾值 - 這意味着用戶是否有權訪問操作。默認實現包含重定向 - 它是twivia,但我需要替換完整的輸出。 – zerkms 2010-04-05 14:18:12

+0

@zerkms:已更新答案,以便爲您提供有關如何替換輸出的更多信息。 – casperOne 2010-04-05 15:00:05

+0

@casperOne:在你的Web.config文件中打開的時候能正常工作嗎?我基於你的解決方案(我從AuthorizeAttribute而不是ActionFilterAttribute派生)有一個稍微不同的方案,當我返回403時,我沒有在Web.config中的中配置好的頁面,而是獲得一個醜陋的IE屏幕。 – 2010-10-20 14:39:35

46

如果用戶進行身份驗證,我會做的是子類AuthorizeAttribute並覆蓋它的HandleUnauthorizedRequest以返回HTTP狀態代碼403。然後,我會將一個system.webServer \ httpErrors部分添加到我的Web.Config中,以用我的自定義頁面替換默認403(最後一部分需要IIS 7+)。具體方法如下:

public class MyAuthorizeAttribute : AuthorizeAttribute { 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { 
     if (filterContext.HttpContext.User.Identity.IsAuthenticated) 
      filterContext.Result = new HttpStatusCodeResult(403); 
     else 
      filterContext.Result = new HttpUnauthorizedResult(); 
    } 
} 

<configuration> 
    <system.webServer> 
    <httpErrors errorMode="Custom" existingResponse="Replace"> 
     <remove statusCode="403" /> 
     <error statusCode="403" responseMode="ExecuteURL" path="/Error/MyCustom403page" /> 
    </httpErrors> 
    </system.webServer> 
</configuration> 
+0

你最好問新的問題;-) – zerkms 2011-06-21 22:12:32

+0

與狀態碼一起,狀態描述也被設置。如何在自定義錯誤403頁面/視圖中獲取此狀態描述? – Vishal 2017-04-07 10:53:12

相關問題