2009-09-17 27 views
12

Tôi đang sử dụng một ActionFilterAttribute để thực hiện logic xác thực tùy chỉnh. Thuộc tính sẽ chỉ được sử dụng trên một lớp Controller có chứa logic xác thực của tôi.ActionFilterAttribute - áp dụng cho các hành động của một loại bộ điều khiển cụ thể

Dưới đây là bộ điều khiển của tôi, có nguồn gốc từ lớp điều khiển tùy chỉnh của tôi, và một thuộc tính mẫu:

public class MyController : CustomControllerBase 
{ 

    [CustomAuthorize(UserType = UserTypes.Admin)] 
    public ActionResult DoSomethingSecure() 
    { 
     return View(); 
    } 

} 

Dưới đây là một ví dụ về ActionFilterAttribute tôi:

public class CustomAuthorizeAttribute : ActionFilterAttribute 
{ 
    public MyUserTypes UserType { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     myUser user = ((CustomControllerBase)filterContext.Controller).User; 

     if(!user.isAuthenticated) 
     { 
     filterContext.RequestContext.HttpContext.Response.StatusCode = 401; 
     } 
    } 
} 

Các công trình lớn.

Đây là câu hỏi: Tôi có thể yêu cầu sử dụng thuộc tính này trên các hành động trong loại bộ điều khiển tùy chỉnh của tôi không?

+1

Thuộc tính của bạn bị hỏng do không được kế thừa từ AuthroizeAttribute và do đó không được đảm bảo chạy khi tác vụ được lưu trong bộ nhớ cache. Xem http://blogs.teamb.com/craigstuntz/2009/09/09/38390/ để biết các giải pháp hoạt động với bộ nhớ đệm. –

+0

Tại sao kết quả hành động được lưu trong bộ nhớ cache? –

+0

Nó sẽ được lưu trữ bởi vì ai đó đã bảo nó được lưu trữ. Hãy tưởng tượng một người nào đó đặt thuộc tính Cache trên một lớp cha, không nhận thấy thuộc tính bị hỏng trên kiểu con. Đó là một ý tưởng tốt hơn để sử dụng một thuộc tính mà về cơ bản không tương thích với bộ nhớ đệm ASP.NET/MVC. Xem liên kết ở trên để biết các tùy chọn. –

Trả lời

14

Bạn có thể đặt ActionFilter trên chính lớp đó. Tất cả các hành động trong lớp sẽ nhận ra ActionFilter.

[CustomAuthorize] 
public class AuthorizedControllerBase : CustomControllerBase 
{ 
} 

public class OpenAccessControllerBase : CustomControllerBase 
{ 
} 

public class MyRealController : AuthorizedControllerBase 
{ 
    // GET: /myrealcontroller/index 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 
+0

Tôi chỉ đang đi lộ trình xác định ActionFilter trong lớp (vì vậy nó không có sẵn trên các lớp khác.) Thật hữu ích khi biết rằng thuộc tính có thể được xác định trên tất cả các ActionResults trong một bộ điều khiển. –

7

Dựa trên nhận xét và ràng buộc của hệ thống của tôi, tôi đã sử dụng phương pháp kết hợp. Về cơ bản, nếu yêu cầu đến thông qua một tuyến đường được lưu trong bộ nhớ cache hoặc "Người dùng" không được đặt vì bất kỳ lý do nào, việc xác thực không thành công theo cách thích hợp.

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    private MyUser User { get; set; } 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
    //Lazy loads the user in the controller. 
    User = ((MyControllerBase)filterContext.Controller).User; 

    base.OnAuthorization(filterContext); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
    bool isAuthorized = false; 
    string retLink = httpContext.Request.Url.AbsolutePath; 

    if(User != null) 
    { 
     isAuthorized = User.IsValidated; 
    } 

    if (!isAuthorized) 
    { 
     //If the current request is coming in via an AJAX call, 
     //simply return a basic 401 status code, otherwise, 
     //redirect to the login page. 
     if (httpContext.Request.IsAjaxRequest()) 
     { 
     httpContext.Response.StatusCode = 401; 
     } 
     else 
     { 
     httpContext.Response.Redirect("/login?retlink=" + retLink); 
     } 
    } 

    return isAuthorized; 
    } 
} 
+0

Nếu bạn đang chuyển hướng trong bất kỳ trường hợp "isAuthorized = false" nào thì tại sao bạn không trả lại đúng vào cuối? – Alex

+0

Trong trường hợp dòng IsAjaxRequest, người dùng không được chuyển hướng, vì vậy phương thức vẫn cần phải trả lại. –

+0

+1 để sử dụng AuthorizeAttribute thay vì ActionFilterAttribute. Giải quyết vấn đề rằng hành động điều khiển có thuộc tính CustomAuthotize được thực hiện ngay cả khi chúng tôi không đăng nhập có thể gây ra các sự cố khác. –

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