2016-06-03 17 views
7

Tôi có một tùy chỉnh AuthorizeAttribute trong một dự án di sản MVC5:phát hiện nếu AuthorizationAttribute tay gọi

public class AuthorizeWithLoggingAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!base.AuthorizeCore(httpContext)) {Log(FilterContext);} 
    } 
} 

Chúng tôi nhận thấy khi nhìn qua các bản ghi, rằng ngoài việc là để áp dụng cho các bộ điều khiển với [AuthorizeWithLogging], nó đã được gọi là một cách rõ ràng ở những nơi khác trong mã, tạo ra các bản ghi giả mạo:

var filters = new FilterInfo(FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor)); 
foreach (var authFilter in filters.AuthorizationFilters) 
{ 
    authFilter.OnAuthorization(authContext); 
    if (authContext.Result != null) {return false;} 
} 

có cách nào để nói (thông qua StackTrace hay một cái gì đó) cho dù phương pháp OnAuthorization đang được một cách rõ ràng Calle d, hoặc được gọi từ thuộc tính? Điều tốt nhất tôi hiện có là Environment.StackTrace.Contains("at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters").

+0

Tại sao bạn không tìm thấy tất cả các tham chiếu đến phương thức 'OnAuthorization' của' AuthorizeAttribute' trong mã của bạn? –

+0

Bạn đang sử dụng phiên bản MVC nào? –

+0

@AmateurProgrammer Tôi đã làm. Họ khó để đánh bật. Nếu chúng ta có thể làm lại tất cả, chúng ta sẽ làm điều đó khác đi. – Arithmomaniac

Trả lời

1

AuthorizeAttribute có một trách nhiệm duy nhất: để xác định xem người dùng có được phép hay không. Điều này có thể được sử dụng ở nhiều nơi trong ứng dụng vì nhiều lý do khác nhau.

Bất kỳ hành động nào được thực hiện do không được ủy quyền (chẳng hạn như trả lại phản hồi HTTP 401) được giao cho người xử lý loại ActionResult được đặt thành thuộc tính AuthorizationContext.Result. Ví dụ, đây là việc thực hiện mặc định của AuthorizeAttribute.HandleUnauthorizedRequest:

protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
{ 
    // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs. 
    filterContext.Result = new HttpUnauthorizedResult(); 
} 

Nếu bạn đang cố gắng để làm kiểm toán khi người dùng là không được phép, bạn nên đặt các kiểm toán vào xử lý ActionResult, không phải trong tùy chỉnh AuthorizeAttribute. Điều này đảm bảo việc kiểm toán chỉ được thực thi nếu ActionResult được thực hiện (nghĩa là, khi trang hiện tại không được ủy quyền), không phải trong mỗi trường hợp ủy quyền được chọn.

public class AuthorizeWithLoggingAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new LoggingActionResult(new HttpUnauthorizedResult(), filterContext); 
    } 
} 

public class LoggingActionResult : ActionResult 
{ 
    private readonly ActionResult innerActionResult; 
    private readonly AuthorizationContext filterContext; 

    public LoggingActionResult(ActionResult innerActionResult, AuthorizationContext filterContext) 
    { 
     if (innerActionResult == null) 
      throw new ArgumentNullException("innerActionResult"); 
     if (filterContext == null) 
      throw new ArgumentNullException("filterContext"); 

     this.innerActionResult = innerActionResult; 
     this.filterContext = filterContext; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     // Do logging (or apparently you want auditing) here 
     Log(this.filterContext); 

     innerActionResult.ExecuteResult(context); 
    } 
} 

Chú ý: Tôi sẽ đặt tên cho chúng AuthorizeWithAuditingAttributeAuditingActionResult kể từ khi bạn muốn rõ ràng kiểm toán, không đăng nhập trong trường hợp này.

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