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

Bài này tiếp tục thực hành, phát triển trên dự án của ví dụ Album trước: Identity (6) - Role trong Identity

Cấu hình Cookie cho Identity

Thực hiện thêm cấu hình sau vào ConfigureServices, thêm sau AddIdentity

services.ConfigureApplicationCookie (options => {
    // options.Cookie.HttpOnly = true;
    // options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    options.LoginPath = $"/login/";
    options.LogoutPath = $"/logout/";
    options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});

Trong đó /login/ là URL để login, thay bằng Url ứng dụng của bạn (Areas/Identity/Pages/Account/Login.cshtml), trang này để ứng dụng chuyển hướng đến nếu truy cập chức năng nào đó cần User phải đăng nhập. /Identity/Account/AccessDenied trang ứng dụng chuyển hướng đến nếu User truy cập chức năng nào đó mà không được phân quyền (không có role được phép truy cập)

Role-based Authorization trong ASP.NET

Role-based Authorization - chứng thực quyền dựa theo Role (vai trò) là cách xác định quyền đơn giản - cơ bản nhất của ASP.NET, cơ bản quyền của User dựa vào Role được gán cho User đó.

Để sử dụng ta dùng đến thuộc tính [Authorize], chỉ thị này áp dụng được cho Controller, Action của Controller, PageModel để xác định ai được quyền truy cập Controller, Action của Controller hay PageModel.

Lưu ý: Với Razor Page - thuộc tính [Authorize] chỉ áp dụng ở mức độ lớp PageModel - không đến mức các Handler. Còn với Controller thì có từ mức cả Controller hay chi tiết đến Action.

[Authorize] đơn giản

Sử dụng [Authorize] có vài tham số, ở trường hợp đơn giản nhất là không có tham số nào. Ở trường hợp này nó cho biết controller, action hay Page Razor chỉ cho các user đã xác thực (đăng ký và đăng nhập) được phép truy cập.

  • Thuộc tính [Authorize] áp dụng cho lớp Controller - thì mọi Action trong Controller ảnh hưởng
  • [Authorize] áp dụng cho Action thì Action bị ảnh hưởng
  • [Authorize] áp dụng cho PageModel thì tất cả các Handler bị ảnh hưởng (không áp dụng được cho từng Handler)

Ví dụ tạo ra một Razor Page như sau: TestAuthorize1

Pages/TestAuthorize1.cshtml

namespace Album.Pages
{
    [Authorize]
    public class TestAuthorize1Model : PageModel
    {
        public void OnGet()
        {
        }
    }
}

Pages/TestAuthorize1.cshtml.cs

@page "/test-authorize-1/"
@inject Microsoft.AspNetCore.Identity.UserManager<Album.Models.AppUser> UserManager
@model Album.Pages.TestAuthorize1Model
<p class="alert alert-danger">@UserManager.GetUserName(User),  Bạn đang truy cập TestAuthorize1</p>

Do khai báo [Authorize]. Truy cập vào /test-authorize-1/ nếu đang đăng nhập thì truy cập được trang

Nếu không đăng nhập thì mọi truy vấn đến các handler của PageModel trên bị không thực hiện được mà nó sẽ tự chuyển về trang login đã cấu hình của Identity

Đối với mô hình MVC khi áp dụng [Authorize] ở tên lớp Controller thì mọi action chịu tác động chứng thực quyền. Đôi khi muốn một Action nào đó bỏ qua kiểm tra quyền thì sử dụng thuộc tính [AllowAnonymous], Ví dụ:

[Authorize] // Mọi action đều kiểm tra user đăng nhập mới thực hiện
public class AccountController : Controller
{
    [AllowAnonymous] // Cho phép User truy cập Action này mà không cần đăng nhập
    public ActionResult Action1()
    {
    }

    public ActionResult Action2()
    {
    }
    /...
}

Hiên nay ASP.NET không có kế hoạch hỗ trợ [Authorize] trên các Handler của Razor Page, trong trường hợp như vậy bạn có thể chuyển sang dùng Controller của MVC hoặc xây dựng một thuộc tính đặt tên AuthorizePageHandler, mã nguồn của nó tại AuthorizeIndexPageHandlerFilter, thì lúc này bạn có thể khai báo chứng thực vào các Handler với [AuthorizePageHandler]

[Authorize] chứng thực theo Role

Bằng cách sử dụng thuộc tính Roles của [Authorize] gán bằng tên các role, thì nó sẽ kiểm tra User phải đăng nhập - user phải có Role liệt kê trong Roles thì mới được truy cập

Ví dụ:

[Authorize(Roles = "Admin")]
public class TestAuthorize1Model : PageModel
{
    / ..
}

Truy cập Page trên User phải được gán Role là Admin

Bạn có thể liệt kê các Role ví dụ: những User có Role Admin và Editor được truy cập

[Authorize(Roles = "Admin,Editor")]

Nếu bạn sử dụng nhiều dòng [Authorize(Roles = "RoleName")] thì User phải được gán tất cả các role đó (thuộc nhóm). Ví dụ User vừa thuộc nhóm Admin vừa thuộc Editor mới được truy cập

[Authorize(Roles = "Admin")]
[Authorize(Roles = "Editor")]
public class TestAuthorize1Model : PageModel
{
}

Trong Controller bạn có thể thiết lập bổ sung [Authorize] cho Action. Ví dụ:

[Authorize(Roles = "Admin, Editor")]
public class MyController : Controller
{
    public ActionResult ActionA()
    {
    }

    [Authorize(Roles = "Admin")]
    public ActionResult ActionnB()
    {
    }
}

User thuộc nhóm Admin, Editor được truy cập Controller MyController, nhưng đến Action ActionB thì chỉ nhóm Admin được truy cập

Nếu một User không có Role chứng thực được truy cập thì nó sẽ chuyển hướng về trang thiết lập trong AccessDeniedPath đã cấu hình trong ConfigureServices của Startup

services.ConfigureApplicationCookie (options => {
    /...
    options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});

Lưu ý: Khi bạn cập nhật Role cho một User nào đó - nếu User đó đang đăng nhập, chưa hết phiên làm việc thì thông tin mới vẫn chưa tác động vào User. Nếu muốn - thời gian nạp lại thông tin User từ Db ngắn hơn thì cấu hình thêm về SecurityStampValidatorOptions trong ConfigureServices như sau:

Tham khảo code ASP_NET_CORE/Album

services.Configure<SecurityStampValidatorOptions>(options =>
{
    // Trên 30 giây truy cập lại sẽ nạp lại thông tin User (Role)
    // SecurityStamp trong bảng User đổi -> nạp lại thông tinn Security
    options.ValidationInterval = TimeSpan.FromSeconds(30);
});
Đăng ký theo dõi ủng hộ kênh