Bỏ qua

12. PHÂN QUYỀN & BẢO MẬT

Hệ thống HRM sử dụng mô hình bảo mật nhiều lớp, kết hợp giữa Role-Based Access Control (RBAC) và Attribute-Based Access Control (ABAC) để đảm bảo dữ liệu nhân sự được truy cập đúng thẩm quyền.

12.1 Authentication (Xác thực)

  • Sử dụng JWT (JSON Web Token) để xác thực người dùng.
  • Mọi API (ngoại trừ login/public) đều yêu cầu JwtAuthGuard.

12.2 Authorization (Phân quyền)

Hệ thống phân quyền dựa trên 3 yếu tố chính:

12.2.1 Role-Based Access Control

Mỗi User có thể có một hoặc nhiều Role (ADMIN, HR, MANAGER, EMPLOYEE). Role định nghĩa các quyền tĩnh (Static Permissions).

Role Mô tả
ADMIN Quản trị viên hệ thống, có toàn quyền (Bypass một số scope).
HR Nhân sự, quản lý quy trình chấm công, tính lương, duyệt phép cấp công ty.
MANAGER Quản lý cấp trung (Trưởng phòng/Trưởng nhóm), xem dữ liệu cấp dưới.
EMPLOYEE Nhân viên thông thường, chỉ xem dữ liệu cá nhân.

12.2.2 Permission-Based Access Control

Sử dụng Guard @PermissionsGuard kết hợp @RequirePermission('action.resource') để kiểm tra quyền truy cập API cụ thể. Ví dụ: @RequirePermission('attendance.review_explanations')

12.2.3 Data Scope Control (Kiểm soát phạm vi dữ liệu)

Đây là lớp bảo mật quan trọng nhất (EmployeeScopeGuard), quyết định xem User có thể xem bản ghi của ai.

Cơ chế Data Scope

  • SELF_ONLY: Chỉ được xem dữ liệu của chính mình (Mặc định cho Employee).
  • TEAM_ONLY: Xem được dữ liệu của mình và các thành viên trong Team do mình làm Leader.
  • DEPARTMENT_ONLY: Xem được dữ liệu của phòng ban do mình làm Head.
  • ALL: Xem được dữ liệu toàn công ty (Dành cho HR/Admin).

Ví dụ luồng kiểm tra (Data Scope Flow):

Luồng kiểm tra EmployeeScopeGuard

  1. Request gọi tới API yêu cầu @EmployeeScoped().
  2. Guard trích xuất targetEmployeeId từ tham số (Params/Body/Query).
  3. Nếu targetEmployeeId == currentUser.employeeId, cho phép (Truy cập chính mình).
  4. Nếu khác, hệ thống kiểm tra cấp độ Manager (Truy vấn phân cấp sơ đồ tổ chức).
  5. Nếu targetEmployeeId là cấp dưới hợp lệ, cho phép. Ngược lại, ném lỗi 403 Forbidden.