C# cơ bản .NET Core

Các Requirement

Requirement (yêu cầu, điều kiện cần đáp ứng) là thành phần trong đó chứa các thông tin để policy sử dụng kiểm tra thông tin của User có đáp ứng yêu cầu đó không. Ví dụ tạo ra policy có tên InGenZ để kiểm tra một User sinh năm từ 1997 đến 2012 thì được truy cập.

Định nghĩa trong ConfigureServices (services.AddAuthorization)

options.AddPolicy("InGenZ", policyBuilder => {
    // ... code sử dụng Requirement hoặc thêm các yêu cầu về Role, Claim
});

Tại trang muốn chứng thực InGenZ cho thêm Attribute: [Authorize(Policy = "InGenZ")]

[Authorize(Policy = "InGenZ")]
public class MyPageModel : PageModel
{
    //...
}

Định nghĩa ra Requirement để sử dụng trong policy InGennZ, Requirement phải được triển khai từ giao diện IAuthorizationRequirement, trong giao diện đó nó không yêu cầu xây dựng một phương thức nào. Ví dụ tạo ra requirement GenZrequirement đơn giản nó chứa thông tin yêu cầu về khoảng năm sinh (MinYear, MaxYear) cần đáp ứng nếu muốn thỏa mãn policy InGenZ

using Microsoft.AspNetCore.Authorization;

public class GenZrequirement : IAuthorizationRequirement
{
    public int MinYear { get; }

    public int MaxYear { get; }

    public GenZrequirement(int _minYear = 1997, int _maxYear = 2012)
    {
        MinYear = _minYear;
        MaxYear = _maxYear;
    }
}

Sửa lại policy InGenZ, cho biết trong policy này có một requirement là một đối tượng lớp GenZrequirement:

options.AddPolicy("InGenZ", policyBuilder => {
    // ... code sử dụng Requirement hoặc thêm các yêu cầu về Role, Claim
    policyBuilder.Requirements.Add(new GenZrequirement(1997, 2012));
});

Lớp khai báo requirement phải có các các property, field là dữ liệu cần đáp ứng

Authorization handler

Các requirement trong policy khi nó tiến hành xác thực quyền (Authorize), nó sẽ được kiểm tra bởi các dịch vụ Authorization Handler, nếu có Authorization Handler nào kiểm tra thông tin user và requirement đó trả về kết quả là có quyền (success) thì người dùng đang truy cập đáp ứng được requirement đó.

Để tạo được các AuthorizationHandler chỉ việc tạo ra các lớp có kế thừa giao diện IAuthorizationHandler, trong lớp đó triển khai phương thức

public Task HandleAsync(AuthorizationHandlerContext context)

Trong phương thức này sẽ kiểm tra thông tin user xem có đáp ứng được requirement không. Sau đây là ví dụ tạo ra AuthorizationHandler đặt tên là AppAuthorizationHandler

 public class AppAuthorizationHandler : IAuthorizationHandler
  {
    private readonly UserManager<AppUser> _userManager;
    private readonly ILogger<AppAuthorizationHandler> _logger;

    // Inject UserManager vào AppAuthorizationHandler
    public AppAuthorizationHandler(UserManager<AppUser> userManager, ILogger<AppAuthorizationHandler> logger)
    {
      _userManager = userManager;
      _logger = logger;
    }

    public Task HandleAsync(AuthorizationHandlerContext context)
    {
      // lấy các requirement chưa được kiểm tra trong ngữ cảnh xác thực hiện tại
      var pendingRequirements = context.PendingRequirements.ToList();
      foreach (var requirement in pendingRequirements)
      {
        // Kiểm tra xem requirement là loại nào để xử lý
        // Nếu requirement là GenZrequirement 
        // gọi IsGenZ để kiểm tra có đáp ứng không  - nếu đáp ứng
        // thì thiết lập đã kiểm tra và đáp ứng bằng 
        // cách gọi context.Succeed(requirement);
        
        // Xử lý nếu requirement là GenZrequirement
        if (requirement is GenZrequirement)
        {
          if (IsGenZ(context.User, context.Resource, requirement))
          {
              _logger.LogInformation("IsGenZ success");
              context.Succeed(requirement);
          }
          else 
          {
            _logger.LogInformation("IsGenZ false");
          }
        }
        else // if is OtherRequirement - có xử lý requirement khác nếu cần, làm tương tự
        {

        }
      }

      return Task.CompletedTask;
    }

    // Phương thức kiểm tra user có đáp ứng requirement GenZrequirement
    private bool IsGenZ(ClaimsPrincipal user, object resource, IAuthorizationRequirement requirement)
    {
        // Lấy ngày sinh của User (Identity có cấu hình bảng User có trường)
        var taskgetuser = _userManager.GetUserAsync(user);
        Task.WaitAll(taskgetuser);
        var appuser = taskgetuser.Result;

        if (appuser.BirthDate == null) return false;
        var require = requirement as GenZrequirement;

        int year = appuser.BirthDate.Value.Year;
        return (year >= require.MinYear && year <= require.MaxYear);

    }
  }

Sau khi có xây dựng được Authorization handler để nó hoạt động cần đăng ký vào DI của hệ thống

// Đăng ký dịch vụ AppAuthorizationHandler vào hệ thống
services.AddTransient<IAuthorizationHandler, AppAuthorizationHandler>();

Từ giờ trở đi, một khi có yêu cầu xác thực quyền [Authorize] - thì các requirement và thông tin User sẽ được chuyển đến AppAuthorizationHandler (kể các các Authorization handler khác, nếu hệ thống có đăng ký nhiều Authorization handler)


Đăng ký nhận bài viết mới