Ủy quyền tùy chỉnh trong Asp.net WebApi - thật là một mớ hỗn độn?


113

Tôi đang đọc từ một số tài nguyên (sách và câu trả lời SO) về ủy quyền trong WebApi.

Giả sử tôi muốn thêm Thuộc tính tùy chỉnh chỉ cho phép truy cập cho Người dùng nhất định:

Trường hợp 1

Tôi đã thấy cách tiếp cận ghi đè này OnAuthorization , đặt phản hồi nếu có gì đó không ổn

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 public override void OnAuthorization(HttpActionContext actionContext)
  {
   if ( /*check if user OK or not*/)
   {
     actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
   }
  }
}

Trường hợp số 2

Nhưng tôi cũng đã thấy ví dụ tương tự này, nó cũng ghi đè OnAuthorizationnhưng với việc gọi tới base:

public override void OnAuthorization(HttpActionContext actionContext) 
{ 
  base.OnAuthorization(actionContext);

    // If not authorized at all, don't bother

    if (actionContext.Response == null)  
     {
      //...
     }
}

Sau đó, bạn kiểm tra xem đã HttpActionContext.Responseđược thiết lập hay chưa. Nếu nó không được đặt, điều đó có nghĩa là yêu cầu đã được ủy quyền và người dùng đồng ý

Trường hợp số 3

Nhưng tôi cũng đã thấy cách tiếp cận ghi đè này IsAuthorized :

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 protected override bool IsAuthorized(HttpActionContext context)
  {
   if ( /*check if user OK or not*/)
   {
    return true;// or false
   }
  }
}

Trường hợp số 4

Và sau đó tôi thấy một ví dụ tương tự nhưng với việc gọi base.IsAuthorized (context):

protected override bool IsAuthorized(HttpActionContext context)
{
 if (something1 && something2 && base.IsAuthorized(context)) //??
 return true;
 return false;
}

Một điều nữa

Và cuối cùng Dominick đã nói ở đây :

Bạn không nên ghi đè OnAuthorization - vì bạn sẽ thiếu khả năng xử lý [AllowAnonymous].

Câu hỏi

  • 1) Tôi nên sử dụng những phương pháp nào: IsAuthorizedhoặc OnAuthorization? (hoặc khi nào thì dùng cái nào)

  • 2) Khi nào tôi nên gọi base.IsAuthorized orbase.OnAuthorization`?

  • 3) Đây có phải là cách họ xây dựng nó? rằng nếu phản hồi là null thì mọi thứ vẫn ổn chứ? (trường hợp số 2)

NB

Xin lưu ý, tôi đang sử dụng (và muốn sử dụng) chỉ AuthorizeAttributemà đã kế thừa từ AuthorizationFilterAttribute

Tại sao ?

Trở thành tôi đang ở giai đoạn đầu tiên trong: http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

nhập mô tả hình ảnh ở đây

Dù sao thì tôi cũng đang hỏi thông qua thuộc tính Authorize mở rộng.


Những gì bạn cần để ghi đè thuộc tính Authorize? Usecase bạn muốn đạt được là gì? Nếu bạn cần cấp quyền truy cập cho một số người dùng nhất định tại sao không sử dụng thuộc tính [Authorize (Users = "Admin")] như thế này?
Taiseer Joudeh

1
@TaiseerJoudeh Ví dụ: Cố gắng giả định người dùng từ 10:00 đến 12:00 (có thể định cấu hình). bạn không thể làm điều đó với Vai trò đơn giản và người đính kèm được ủy quyền. bạn phải thực hiện logic của riêng bạn
Royi Namir

Câu trả lời:


93

Tôi nên sử dụng những phương pháp nào: IsAuthorized hay OnAuthorization? (hoặc khi nào thì dùng cái nào)

Bạn sẽ gia hạn AuthorizationFilterAttributenếu logic ủy quyền của bạn không phụ thuộc vào danh tính được thiết lập và vai trò. Đối với ủy quyền liên quan đến người dùng, bạn sẽ mở rộng và sử dụng AuthorizeAttribute. Đối với trường hợp cũ, bạn sẽ ghi đè OnAuthorization. Đối với trường hợp sau, bạn sẽ ghi đè IsAuthorized. Như bạn có thể thấy từ mã nguồn của các thuộc tính này, OnAuthorizationđược đánh dấu ảo để bạn ghi đè nếu bạn lấy từ đó AuthorizationFilterAttribute. Mặt khác, IsAuthorizedphương thức được đánh dấu ảo trong AuthorizeAttribute. Tôi tin rằng đây là một gợi ý tốt cho mục đích sử dụng.

khi nào tôi nên gọi base.IsAuthorized hay base.OnAuthorization?

Câu trả lời cho câu hỏi này nằm ở cách OO nói chung hoạt động. Nếu bạn ghi đè một phương thức, bạn có thể hoàn toàn cung cấp một triển khai mới hoặc khôi phục lại triển khai do cha mẹ cung cấp và nâng cao hành vi. Ví dụ, lấy trường hợp củaIsAuthorized(HttpActionContext) . Hành vi của lớp cơ sở là kiểm tra người dùng / vai trò so với những gì được chỉ định trong bộ lọc so với danh tính được thiết lập. Giả sử, bạn muốn làm tất cả những điều đó nhưng ngoài ra, bạn muốn kiểm tra điều gì khác, có thể dựa trên tiêu đề yêu cầu hoặc thứ gì đó. Trong trường hợp đó, bạn có thể cung cấp ghi đè như thế này.

protected override bool IsAuthorized(HttpActionContext actionContext)
{
    bool isAuthroized = base.IsAuthorized(actionContext);
    // Here you look at the header and do your additional stuff based on actionContext
    // and store the result in isRequestHeaderOk
    // Then, you can combine the results
    // return isAuthorized && isRequestHeaderOk;
}

Tôi xin lỗi nhưng không hiểu Q3 của bạn. BTW, Bộ lọc ủy quyền đã có từ rất lâu và mọi người sử dụng nó cho mọi thứ và đôi khi cũng không chính xác.

Một điều nữa. Và cuối cùng, anh chàng này ở đây đã nói: Bạn không nên ghi đè OnAuthorization - bởi vì bạn sẽ thiếu khả năng xử lý [AllowAnonymous].

Người đã nói đó là Thần kiểm soát ra vào - Dominick. Rõ ràng là nó sẽ đúng. Nếu bạn nhìn vào việc triển khai OnAuthorization(được sao chép bên dưới),

public override void OnAuthorization(HttpActionContext actionContext)
{
    if (actionContext == null)
    {
        throw Error.ArgumentNull("actionContext");
    }

    if (SkipAuthorization(actionContext))
    {
        return;
    }

    if (!IsAuthorized(actionContext))
    {
        HandleUnauthorizedRequest(actionContext);
    }
}

lệnh gọi đến SkipAuthorizationlà phần đảm bảo AllowAnonymousbộ lọc được áp dụng, nghĩa là, cấp quyền bị bỏ qua. Nếu bạn ghi đè phương thức này, bạn sẽ mất hành vi đó. Trên thực tế, nếu bạn quyết định phân quyền dựa trên người dùng / vai trò, tại thời điểm đó, bạn sẽ quyết định xuất phát từ đâu AuthorizeAttribute. Chỉ có tùy chọn đúng còn lại cho bạn tại thời điểm đó sẽ là ghi đè IsAuthorizedchứ không phải tùy chọn đã được ghi đè OnAuthorization, mặc dù về mặt kỹ thuật bạn hoàn toàn có thể làm được.

Tái bút. Trong ASP.NET Web API, có một bộ lọc khác được gọi là bộ lọc xác thực. Ý tưởng là bạn sử dụng nó để xác thực và bộ lọc ủy quyền để ủy quyền, như tên cho biết. Tuy nhiên, có rất nhiều ví dụ trong đó ranh giới này bị mờ đi. Rất nhiều ví dụ về bộ lọc xác thực sẽ thực hiện một số loại xác thực. Dù sao, nếu bạn có thời gian và muốn hiểu thêm một chút, hãy xem bài viết MSDN này . Disclaimer: Nó được viết bởi tôi.


Cảm ơn một lần nữa, nhưng nếu tôi đọc giữa các dòng, IsAuthenticated được gọi bởi OnAuthirization, vậy tại sao không ghi đè OnAuthorization và gọi base.OnAuthorization rồi kiểm tra phản hồi?
Royi Namir

Bạn chắc chắn có thể, nếu đó là những gì bạn muốn.
Badri

Trong câu hỏi thứ ba của tôi, ý tôi là: sau khi chạy hàm cơ sở - chẳng hạn như base.OnAuthorization, cách duy nhất để kiểm tra xem nó có thành công không - là kiểm tra thuộc tính Response ?, ps các ví dụ lấy từ sách của bạn :-)
Royi Namir

Có, thông thường bạn tìm mã trạng thái 401 nhưng không phải null, theo như tôi biết. BTW, tôi không nhớ đã viết về ghi đè OnAuthorizationtrong sách của mình. Tôi chắc chắn tôi sẽ không có văn bản về việc kiểm tra phản ứng cho null, coz đây là lần đầu tiên tôi nghe về nó :)
Badri

Vâng, tôi đã nhầm lẫn với cuốn sách khác. Tôi đang đọc đồng thời 3 cuốn sách: bí mật (của bạn), thực tế (của bạn) và webapi chuyên nghiệp (của Tugberk, Zeitler, Ali). NHƯ bạn có thể thấy - họ đã làm điều đó ở đó: i.stack.imgur.com/LNGi4.jpg - họ vừa kiểm tra xem null, vậy tôi nên kiểm tra mã null hay mã lỗi?
Royi Namir

18

Được rồi, đề xuất của tôi là thực hiện như sau, giả sử rằng bạn đang sử dụng mã thông báo mang OAuth để bảo vệ API Web của mình và bạn đang đặt Thời gian được phép làm xác nhận quyền sở hữu cho người dùng khi bạn phát hành mã thông báo. Bạn có thể đọc thêm về xác thực dựa trên mã thông báo tại đây

  1. Tạo CustomAuthorizeAttribute có nguồn gốc từ AuthorizationFilterAttribute
  2. phương pháp ghi đè OnAuthorizationAsyncvà sử dụng mã mẫu bên dưới:

     public class CustomAuthorizeAttribute : AuthorizationFilterAttribute
    {
    
        public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
        {
    
            var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
    
            if (!principal.Identity.IsAuthenticated)
            {
                return Task.FromResult<object>(null);
            }
    
            var userName = principal.FindFirst(ClaimTypes.Name).Value;
            var userAllowedTime = principal.FindFirst("userAllowedTime").Value;
    
            if (currentTime != userAllowedTime)
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Not allowed to access...bla bla");
                return Task.FromResult<object>(null);
            }
    
            //User is Authorized, complete execution
            return Task.FromResult<object>(null);
    
        }
    }
  3. Bây giờ trong bộ điều khiển của bạn, bạn sử dụng thuộc tính CustomAuthorize để bảo vệ bộ điều khiển của bạn bằng cách sử dụng logic ủy quyền này.

1
Cảm ơn. Nhưng tôi hiện đang sử dụng AuthorizeAttributemà không kế thừa AuthorizationFilterAttributevà -Cũng cho việc học tôi đặc biệt yêu cầu về những phương pháp tôi nên sử dụng và về phản ứng có nội dung hay không thingy ...
Royi Namir

3

ASP.NET v5 đã giới thiệu Hệ thống ủy quyền hoàn toàn mới. Đối với những người sắp sử dụng .NET 5, tôi khuyên bạn nên chuyển sang Microsoft.AspNet.Authorization.

Khá nhiều nó kết thúc sự lộn xộn do giữ cả hai System.Web.Http.AuthorizeSystem.Web.Mvc.Authorize và các triển khai xác thực cũ hơn khác.

Nó cung cấp một bản tóm tắt rất tốt về các Loại hành động (Tạo, Đọc, Cập nhật, Xóa), Tài nguyên, Vai trò, Yêu cầu, Chế độ xem, Yêu cầu tùy chỉnh và cho phép xây dựng Trình xử lý tùy chỉnh, kết hợp bất kỳ điều nào ở trên. Ngoài ra, những trình xử lý này cũng có thể được sử dụng kết hợp.

Trong ASP.NET v5, ủy quyền hiện cung cấp vai trò khai báo đơn giản và mô hình dựa trên chính sách phong phú hơn trong đó ủy quyền được thể hiện trong các yêu cầu và trình xử lý đánh giá yêu cầu của người dùng so với các yêu cầu. Kiểm tra bắt buộc có thể dựa trên các chính sách hoặc chính sách đơn giản đánh giá cả danh tính người dùng và thuộc tính của tài nguyên mà người dùng đang cố gắng truy cập.


14
Tốt để biết, nhưng không trả lời câu hỏi nào cả.
Zero3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.