Có thể chạy tất cả các trình xử lý cho một chính sách nội tuyến thay vì với một thuộc tính?


8

Trên hầu hết các API của tôi, tôi chỉ đơn giản là ủy quyền như thế này:

[Authorize(Policy = "Foo")]
public MyApi()

Tôi nhận được chính sách này từ NuGet và không thể sửa đổi nó.

Đối với một số API của tôi, tôi không muốn có chính sách này. Điều này cần phải được tìm ra trong thời gian chạy dựa trên một số cấu hình. Tôi muốn một số cách để chạy nội tuyến này và đảm bảo tất cả các trình xử lý được thiết lập chạy.

Sau rất nhiều lần tìm kiếm, tôi thấy rằng tôi đã tạo IAuthorizationServicevà sử dụng nó để gọi AuthorizeAsync. Điều này có vẻ như đó là những gì tôi muốn, nhưng vấn đề tôi đang gặp phải bây giờ là tất cả các trình xử lý đều dựa vào AuthorizationFilterContexttài nguyên trên bối cảnh. Điều này dường như tự động xảy ra khi Ủy quyền được thực hiện thông qua thuộc tính, nhưng không thông qua lệnh gọi AuthorizeAsync. Nó cần phải được thông qua bằng tay trong trường hợp này. Mã của tôi bây giờ trông như thế này:

public MyApi()
{
    var allowed = await _authorizationService.AuthorizeAsync(User, null, "Foo").ConfigureAwait(false);
}

Điều này dường như đi qua tất cả các trình xử lý của tôi một cách chính xác, nhưng chúng không hoạt động do thiếu AuthorizationFilterContext.

1) Đây có phải là cách tiếp cận chính xác để bắt đầu, hoặc có một số cách khác để làm điều này nội tuyến? Tôi đoán có lẽ có một số cách để tạo chính sách của riêng mình bao bọc chính sách này và tôi có thể kiểm tra cấu hình ở đó, nhưng nếu có một cách tiếp cận nội tuyến đơn giản thì tôi thích điều đó hơn.

2) Nếu cách này là hợp lệ, có cách nào tốt để có được AuthorizationFilterContextkhông? Tôi đã thử tạo nó bằng tay, nhưng tôi sợ điều này không thực sự chính xác mà không truyền thêm dữ liệu từ ngữ cảnh, nhưng tôi không thể tìm thấy bất kỳ ví dụ / tài liệu hay nào:

new AuthorizationFilterContext(new ActionContext(HttpContext, HttpContext.GetRouteData(), new ActionDescriptor()), new IFilterMetadata[] { });


Đây là một cách thực sự xấu để làm điều đó. Trước hết, bất kỳ cuộc gọi nào cũng có thể đạt được phương thức api của bạn ngay cả khi họ không có quyền truy cập vì bạn thực hiện kiểm tra truy cập vào thời điểm sau. Tạo một thuộc tính tùy chỉnh cho chính bạn và bạn có thể dễ dàng kiểm tra bất kỳ chính sách nào (dù là đơn hay nhiều) mà bạn muốn kiểm tra có thuộc sở hữu của người dùng hay không. Cũng tốt để đọc điều này: docs.microsoft.com/en-us/aspnet/ cốt lõi / bảo mật / ủy quyền / trên mạng
tò mòBoy

Câu trả lời:


-2

Sẽ không có AuthorizationFilterContextkhi bạn ở ngoài đường ống ủy quyền. Do đó, bạn không nên xử lý nội tuyến xác thực với IAuthorizationService.

Điều này dường như đi qua tất cả các trình xử lý của tôi một cách chính xác, nhưng chúng không hoạt động do thiếu AuthorizationFilterContext.

Âm thanh như bạn có quyền kiểm soát các trình xử lý xác thực. Bạn đã thử xác thực ngắn mạch bên trong trình xử lý nếu không bắt buộc?

Trình xử lý có thể nhận các dịch vụ thông qua DI để bạn có thể đặt cấu hình thời gian chạy yêu cầu của mình thông qua IOptions hoặc IHttpContextAccessor và những gì đã từng có.


-2

Bạn không thể tạo Authorizethuộc tính của riêng bạn mà sẽ kế thừa thuộc tính hiện tại và giải quyết chính sách trong nội bộ? Hoặc thậm chí tốt hơn thử sử dụngIAuthorizationPolicyProvider

class MyPolicyProvider : IAuthorizationPolicyProvider
{
    private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }

    public MyPolicyProvider()
    {
        BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
    }

    public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        if (policyName.Equals("Foo"))
        {
            bool myConditionToAvoidPolicy = true;
            if (myConditionToAvoidPolicy)
            {
                return Task.FromResult<AuthorizationPolicy>(null);
            }
        }

        return BackupPolicyProvider.GetPolicyAsync(policyName);
    }
}

Điều này không được thử nghiệm, nhưng bạn có thể tìm hiểu thêm về nó ở đây .


-2

Tình trạng kiểm tra của bạn có vẻ như xảy ra ở thời điểm sau mà tôi không nghĩ rằng đó là một ý tưởng tốt. Phương pháp api của bạn đang bị tổn thương và vẫn mở khi kiểm tra của bạn được thực hiện tại thời điểm sau. Nhưng bằng cách sử dụng thuộc tính, bạn có thể nắm bắt nó ở cấp độ trước đó và vẫn có thể áp dụng logic tùy chỉnh. Vào cuối ngày, tất cả những gì nó quyết định là "có, có quyền truy cập" hoặc "không, không có quyền truy cập cho bạn !!" Dưới đây không được thử nghiệm nhưng sẽ giúp bạn đi:

public class CustomAuthorize : AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
        if (!currentIdentity.IsAuthenticated) {
            // no access
        }

        bool myCondition = "money" == "happiness"; 
        if(myCondition){
           // do your magic here...
        }
        else{
          // another magic...
       }           
    }
}
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.