2010-01-13 18 views
7

Tôi đã triển khai thành công ủy quyền dựa trên vai trò trong ASP.NET. Khi một người không có vai trò cần thiết, anh ta sẽ thấy trang lỗi cho 401.2 không được ủy quyền.customerrors cho 401.2 trong ASP.NET

Điều tôi muốn thực hiện bây giờ là có một trang 401 tùy chỉnh trong ứng dụng của mình và chuyển nó đến đó qua các cài đặt trong web.config. Tôi đã thử điều này:

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> 
    <error statusCode="401" redirect="NoAccess.htm" /> 
</customErrors> 

Nhưng điều này không bị bắt. Tôi có phải ghi đè lên nó trong IIS để thay thế? Tôi hy vọng không như vậy sẽ khiến mọi thứ trở nên khó khăn hơn.

Trả lời

7

Tôi đã gặp sự cố tương tự gần đây và nó chỉ ra rằng đây là một trong những điều kỳ quặc khi sử dụng Xác thực Windows.

Joshua Flanagan đã tạo một nice HttpModule một trong khi trước đây sẽ tôn trọng phần CustomErrors trong web.config của bạn và chuyển hướng đến trang lỗi 401.

Chìa khóa để giải pháp là để đánh chặn các sự kiện EndRequest của vòng đời trang, kiểm tra mã 401 trạng thái, và sau đó thực hiện trang tùy chỉnh của bạn.

Tính di động của HttpModule rất tốt vì nó làm cho giải pháp có thể tái sử dụng và giữ Global.asax của bạn sạch sẽ, nhưng không có gì ngăn bạn kết nối sự kiện EndRequest của bạn trong Global.asax với mã của bạn nếu bạn thực sự muốn.

Nếu bạn đang sử dụng ASP.NET MVC, giải pháp này không hoàn toàn thanh lịch.

3

Nếu bạn không muốn thêm một HttpModule

trong web.config

<system.web> 
    <customErrors mode="On" defaultRedirect="~/MyController/MyErrorAction/" redirectMode="ResponseRedirect"> 
     <error statusCode="401" redirect="~/MyController/MyErrorAction/" /> 
    </customErrors> 

trong global.asax.cs

protected void Application_EndRequest(object sender, EventArgs e) 
    { 
     HttpApplication application = (HttpApplication)sender; 

     if (application.Response.StatusCode != 401 || !application.Request.IsAuthenticated) return; 

     application.Response.ClearContent(); 

     //You can replace the piece below is to redirect using MVC, or your can replace all this with application.Server.Execute(yourPage); 
     IController errorController = new SharedController(); 
     var rd = new RouteData(); 
     rd.Values.Add("controller", "MyController"); 
     rd.Values.Add("action", "MyErrorAction"); 
     rd.Values.Add("value", "You or your user group do not have permissions to use the address: " + Request.Url.PathAndQuery); 

     errorController.Execute(new RequestContext(new HttpContextWrapper(Context), rd)); 
     HttpContext.Current.Server.ClearError(); 
    } 
+0

Phủ định của IsAuthenticated có thực sự chính xác không? Không phải nó là một cách khác xung quanh, tức là nếu xác thực => trả về từ phương pháp? – aeliusd

3

Dưới đây là một MVC thuyết bất khả tri biến thể:

Trong Web.config

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> 
    <error statusCode="401" redirect="NoAccess.htm" /> 
</customErrors> 

Trong Global.asax.cs

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    HttpApplication application = (HttpApplication)sender; 

    if (application.Response.StatusCode != 401 || !application.Request.IsAuthenticated) return; 

    var customErrors = (CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors"); 

    var accessDeniedPath = customErrors.Errors["401"] != null ? customErrors.Errors["401"].Redirect : customErrors.DefaultRedirect; 
    if (string.IsNullOrEmpty(accessDeniedPath)) 
     return; // Let other code handle it (probably IIS). 

    application.Response.ClearContent(); 
    application.Server.Execute(accessDeniedPath); 
    HttpContext.Current.Server.ClearError(); 
} 
2

Đây là những gì làm việc tốt cho tôi.

Global.asax -

protected void Application_EndRequest(object sender, EventArgs e) 
    { 
     if (Response.StatusCode == 401 && Request.IsAuthenticated) 
     { 
      Response.StatusCode = 303; 
      Response.Clear(); 
      Response.Redirect("~/AccessDenied.html"); 
      Response.End(); 
     } 
    } 

Web.config -

<system.web> 
    <customErrors mode="On"> 
     <error statusCode="401" redirect="AccessDenied.html"/> 
    </customErrors> 
    <authentication mode="Windows"/> 
    </system.web> 
    <location path="AccessDenied.html"> 
    <system.web> 
     <authorization> 
     <allow roles="*"/> 
     </authorization> 
    </system.web> 
    </location> 
    <location path="."> 
    <system.web> 
     <authorization> 
     <allow roles="YourADGroup"/> 
     <deny users="*" /> 
     </authorization> 
    </system.web> 
    </location> 

này sẽ chăm sóc của các đôi 401 trước một vấn đề 200 là tốt. Cũng phá vỡ popup xác thực firefox pesky.

Các vấn đề liên quan