C# Cơ bản .NET Core §1 Cài đặt, chương trình C# đầu tiên §2 Biến, kiểu dữ liệu và nhập/xuất §3 Toán tử số học và gán §4 So sánh, logic và lệnh if, switch §5 Vòng lặp for, while §6 Phương thức - Method §7 Chuyển số thành chữ §8 Phương thức - Delegate §9 Lớp - Class §10 Namespace §11 Partial, Nested §12 Kiểu giá trị, tham chiếu §13 Kiểu vô danh và dynamic §14 Biểu thức lambda §15 Event §16 Hàm hủy - Quá tải toán tử - thành viên tĩnh - indexer §17 null và nullable §18 Mảng §19 Chuỗi ký tự §20 Tính kế thừa §21 Phương thức khởi tạo §22 Tính đa hình - abstract - interface §23 Struct và Enum §24 Ngoại lệ Exeption §25 IDisposable - using §26 File cơ bản §27 FileStream §28 Generic §29 Collection - List §30 SortedList §31 Queue / Stack §32 Linkedlist §33 Dictionary - HashSet §34 Phương thức mở rộng §35 ObservableCollection §36 LINQ §37 (Multithreading) async - bất đồng bộ §38 Type §39 Attribute Annotation §40 DI Dependency Injection §41 (Multithreading) Parallel §42 Thư viện lớp §43 (Networking) Uri, Dns, Ping §44 (Networking) HttpClient §45 (Networking) HttpMessageHandler §46 (Networking) HttpListener §47 (Networking) Tcp TcpListenerr/TcpClient §48 (ADO.NET) SqlConnection §49 (ADO.NET) SqlCommand §50 (ADO.NET) DataAdapter §51 (EF Core) Tổng quan §52 (EF Core) Tạo Model §53 (EF Core) Fluent API §54 (EF Core) Query §55 (EF Core) Scaffold §56 (EF Core) Migration §57 (ASP.NET CORE) Hello World! §58 (ASP.NET CORE) Middleware §59 (ASP.NET CORE) Map - Request - Response §60 (ASP.NET CORE) IServiceCollection - MapWhen §61 (ASP.NET CORE) Session - ISession §62 (ASP.NET CORE) Configuration §63 (ASP.NET CORE) Gửi Mail §64 (ASP.NET CORE) SASS/SCSS §65 (ASP.NET CORE) LibMan §66 (ASP.NET RAZOR) Khởi tạo và Route §67 (ASP.NET RAZOR) Cú pháp Razor §68 (ASP.NET RAZOR) Layout trong ASP.NET Core §69 (ASP.NET RAZOR) Partial §70 (ASP.NET RAZOR) ViewComponent §71 (ASP.NET RAZOR) TagHelper §72 (ASP.NET RAZOR) HtmlHelper §73 (ASP.NET RAZOR) PageModel §74 (ASP.NET RAZOR) Model Binding §75 (ASP.NET RAZOR) HTML Form, Validation §76 (ASP.NET RAZOR) Upload File §77 (ASP.NET RAZOR) Entity Framework §78 (ASP.NET RAZOR) Paging §79 (ASP.NET RAZOR) Identity (1) - Register, Login, Logout §80 (ASP.NET RAZOR) Identity (2) Lockout, Reset Password §81 (ASP.NET RAZOR) Identity (3) Google Login §82 (ASP.NET RAZOR) Identity (4) Facebook Login §83 (ASP.NET RAZOR) Identity (5) profile, password, email ... §84 (ASP.NET RAZOR) Identity (6) Role §85 (ASP.NET RAZOR) Identity (7) Role-based Authorization §86 (ASP.NET RAZOR) Identity (8) RoleClaim §87 (ASP.NET RAZOR) Identity (9) Authorization Handler §88 (ASP.NET RAZOR) IAuthorizationService §89 (ASP.NET MVC) Controller - View §90 (ASP.NET MVC) Route §91 (ASP.NET MVC) EF, Identity §92 (ASP.NET MVC) Binding, Validation §93 (ASP.NET MVC) Xây dựng Website(1) §94 (ASP.NET MVC) Xây dựng Website(2) §95 (ASP.NET MVC) Xây dựng Website(3) §96 (ASP.NET MVC) Xây dựng Website(4) §97 (ASP.NET MVC) Giỏ hàng - Cart (5) §98 (ASP.NET MVC) elFinder (5) §99 (ASP.NET MVC) SB Admin (6) §100 (ASP.NET MVC) Kestrel, publish

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)