2012-06-07 32 views
18

Tôi đã đọcChuyển đến một trang khác khi người dùng không được uỷ quyền trong asp.net MVC3

How to easily redirect if not authenticated in MVC 3?Redirect to AccessDenied page when user is not authorized nhưng liên kết từ một câu trả lời (nghĩa http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/) không hoạt động.

tôi đặt

[Authorize(Users = "test")] 
    public class RestrictedPageController: Controller 
    { 

     public ActionResult Index() 
     { 
      return View(); 
     } 

.... 
    } 

Và trong web.config của tôi, tôi đã có

<authentication mode="Forms"> 
     <forms loginUrl="~/Account/LogOn" timeout="2880" /> 
</authentication> 

phù hợp với https://stackoverflow.com/a/6770583/998696

Nhưng khi tôi muốn truy cập /RestrictedPage/Index, nó phải chuyển hướng tôi đến trang khác (từ bộ điều khiển khác). Thay vì điều này, các lỗi xuất hiện như:

Server Error in '/Project' Application. 

The view 'LogOn' or its master was not found or no view engine supports the searched locations. The following locations were searched: 
~/Views/Account/LogOn.aspx 
~/Views/Account/LogOn.ascx 
~/Views/Shared/LogOn.aspx 
~/Views/Shared/LogOn.ascx 
~/Views/Account/LogOn.cshtml 
~/Views/Account/LogOn.vbhtml 
~/Views/Shared/LogOn.cshtml 
~/Views/Shared/LogOn.vbhtml 

Trước khi đăng nhập, hình thức Logon trang xuất hiện một cách chính xác nhưng lỗi ở trên xuất hiện khi truy cập vào trang /RestrictedPage/Index. Tôi có thể đăng nhập với người dùng khác được ủy quyền để truy cập trang RestrictedPage.

Lỗi của tôi và cách chuyển hướng thiết lập ở đâu?

Trả lời

47

Giá trị mặc định Authorize thuộc tính cư xử theo cách như vậy mà khi người dùng là không được xác thực hoặc chứng thực nhưng không được uỷ quyền sau đó nó thiết lập các mã trạng thái là 401 (Không được phép). Khi bộ lọc đặt mã trạng thái là kiểm tra khung ASP.NET nếu trang web đã bật xác thực biểu mẫu và nếu nó được chuyển hướng đến tham số loginUrl được thiết lập ở đó.

Nếu bạn muốn thay đổi hành vi đó nói rằng bạn muốn chuyển hướng người dùng đến bộ điều khiển AccessDenied nếu người dùng được xác thực nhưng không được ủy quyền thì bạn phải mở rộng thuộc tính Authorize và ghi đè phương thức HandleUnauthorizedRequest.

Ví dụ:

public class CustomAuthorize: AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
     else 
     { 
      filterContext.Result = new RedirectToRouteResult(new 
       RouteValueDictionary(new { controller = "AccessDenied" })); 
     } 
    } 
} 

Bạn có thể ghi đè lên HandleUnauthorizedRequest theo nhu cầu của bạn và sau đó bạn phải đánh dấu các hành động điều khiển để sử dụng thuộc tính CustomAuthorize thay vì được xây dựng trong một.

+0

Upvote và chấp nhận! Một lưu ý: phải sử dụng 'protected override void HandleUnauthorizedRequest (AuthorizationContext filterContext) {' để ghi đè lên phương thức, nếu không sẽ không hoạt động –

+0

Cảm ơn bạn đã chỉ rằng .. cố định atonce! – VJAI

1

Vâng, đó là chính xác như bạn đề cập đến trong web.config

<forms loginUrl="~/Account/LogOn" timeout="2880" /> 

chuyển hướng đang tìm kiếm điều khiển tài khoản và đăng nhập ActionResult. Nếu bạn muốn chuyển hướng trang web của bạn, thay đổi có thay vì tài khoản và đăng nhập

2

Place "/ tài khoản/đăng nhập" Thay vì "~/tài khoản/đăng nhập"

3

Tôi thích trả lời của Mark,
nhưng tôi không muốn thay đổi tất cả các hành động của tôi thuộc tính
từ [Duyệt] tới [CustomAuthorize]

tôi sửa Login() hành động trên AccountController
và kiểm tra Request.IsAuthenticated trước show xem
tôi nghĩ rằng, nếu người sử dụng chứng thực đi đến /Account/Logon,
tôi sẽ chuyển hướng đến /Error/AccessDenied.

[AllowAnonymous] 
    public ActionResult Login(string returnUrl) 
    { 
     if (Request.IsAuthenticated) 
     { 
      return RedirectToAction("AccessDenied", "Error"); 
     } 

     ViewBag.ReturnUrl = returnUrl; 

     return View(); 
    } 
+0

nhưng trong trường hợp này, nếu bạn đã đăng nhập và vào trang đăng nhập, bạn sẽ thấy một '/ error/accessDenied' thay vì'/account/login', phải không? Nếu bạn không muốn thay đổi '[Ủy quyền] thành' [CustomAuthorize] ', bạn luôn có thể đặt tên nó là' YourBrand.YourProject.Security.AuthorizeAttribute' và sau đó chỉ thực hiện tham chiếu đến 'YourBrand.YourProject.Security' hoặc một cái gì đó – percebus

0

Vì tôi không muốn ghi đè AuthorizeAttribute tôi đã sử dụng bộ lọc

public class RedirectFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 

     if (!IsAuthorized(filterContext)) 
     { 
      filterContext.Result = 
       new RedirectToRouteResult(new RouteValueDictionary(new {controller = "AccessDenied"})); 
     } 
    } 

    private bool IsAuthorized(ActionExecutingContext filterContext) 
    { 
     var descriptor = filterContext.ActionDescriptor; 
     var authorizeAttr = descriptor.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute; 

     if (authorizeAttr != null) 
     { 
      if(!authorizeAttr.Users.Contains(filterContext.HttpContext.User.ToString())) 
      return false; 
     } 
     return true; 

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