Giải pháp cho bài toán phân quyền sử dụng Keycloak
Trong mỗi ứng dụng hiện nay, nhu cầu phân quyền là rất phổ biến, do đó trong bài viết này, chúng ta sẽ tập trung giải quyết một bài toán cụ thể sử dụng Keycloak. Dành cho ai chưa biết, Keycloak là một giải pháp quản lý danh tính và truy cập (IAM) mã nguồn mở được sử dụng rộng rãi với các tính năng: Xác thực, ủy quyền, quản lý người dùng và bảo mật (theo Gemini).
Tuy nhiên, bài viết này sẽ không đi sâu vào việc cài đặt hay tích hợp Keycloak vì đã có rất nhiều hướng dẫn làm rồi, thay vào đó chúng ta sẽ tập trung vào việc cấu hình với giao diện để đảm bảo các yêu cầu về phân quyền (điều mà khi mình tìm hiểu thấy khá ít trên mạng). Mọi người có thể đọc thêm tại đây để hiểu hơn về các bước phân quyền của Keycloak.
Bài toán
- Phân quyền cho ứng dụng trường học theo các chức năng: quản lý sách, quản lý học sinh và quản lý truy cập với 2 quyền đọc, ghi.
- User sẽ có nhiều vị trí theo mô hình phân cấp, mỗi vị trí sẽ có những quyền mặc định.
- Khi thêm user mới sẽ tự động có các quyền mặc định.
- Admin có thể thêm / bớt quyền theo các chức năng cho từng user.
Ý tưởng
Kết hợp 2 chiến lược phân quyền là Role-based access control (RBAC) và User-based access control (UBAC) mà Keycloak cung cấp.
Cấu hình
Sau đây chúng ta sẽ tiến hành cấu hình theo các bước:
1. Tạo các Resource theo chức năng
2. Tạo các Scope đọc ghi
Như vậy là chúng ta đã giải quyết được ý đầu tiên khi chia các api theo resource và tạo ra 2 scope.
3. Tạo ra các group theo mô hình phân quyền
Mình sẽ tạo trường học với 3 phòng ban.
4. Tạo ra các role tương ứng và gán với các group
Mọi người có thể dùng Realm role hoặc Client role tùy theo nhu cầu, ở đây mình sử dụng Client role
Sau khi tạo xong và gán role vào group thì ví dụ group dev team sẽ có cả role của team và company
Vậy là đã xong ý 2 của bài toán. 2 ý tiếp theo sẽ liên quan nhiều đến permission và policy nên nếu bạn nào chưa nắm rõ về hai khái niệm này của Keycloak thì nên đọc lại để phần sau dễ hiểu hơn.
5. Tạo ra các policy tương ứng với các role trên
6. Tạo ra các permission với resource và scope
Thông thường các permission là tổ hợp của resource và scope nên chỉ cần 2 permission để đảm bảo 2 scope đọc ghi. Tuy nhiên để đảm bảo cho việc phân quyền theo từng user ở bước sau, chúng ta sẽ tạo thêm 2 permission negative với cấu hình resource, scope tương tự.
Với 2 permission thường ta sẽ để Decision strategy là Affirmative (tương ứng với điều kiện OR) để mỗi policy được cấu hình đều có permission. Ngược lại, với 2 permission negative chúng ta sẽ để Decision strategy là Unanimous (điều kiện AND)
Với mỗi permission, chúng ta sẽ gán với các policy để đảm bảo các quyền mặc định theo từng vị trí, ví dụ quyền đọc sách sẽ được gán cho mọi nhân viên (chưa gán gì cho permission negative)
Vậy là với các permission và policy kể trên, khi tạo mới 1 user và gán vào group nhất định sẽ có các quyền mặc định.
Ví dụ với user "anhho" được gán cho group "dev-team" sẽ mặc định có permission "book::read"
Cuối cùng với nhu cầu phân quyền tùy biến theo từng user, chúng ta sẽ phải tạo thêm các policy và sử dụng các permission negative đã tạo phía trên.
7. Tạo thêm policy với user tùy biến
Với user "anhho" cần tùy biến, chúng ta tạo 2 User policy, 1 với logic positive, 1 với logic negative.
Dev "anhho" thông thường không có quyền "book::write", tuy nhiên admin đặc biệt thêm quyền cho user này
Sau đó, dù dev mặc định có quyền "book::read", admin muốn loại quyền này với dev "anhho"
Khi đó user "anhho" sẽ không còn quyền mặc định "book::read"
Kết bài
Vậy là chúng ta đã cùng nhau giải quyết tất cả các yêu cầu về phân quyền sử dụng Keycloak mà chưa cần code một dòng nào (không tính nỗ lực để dựng nó lên). Mở rộng hơn, chúng ta có thể dùng SDK của Keycloak để quản lý permission cho ứng dụng.
Lời cuối, chúc anh em một năm mới nhiều sức khỏe, thành công trong công việc và tìm được nhiều niềm vui khi code
All rights reserved