Tôi biết mình đã trễ hơn 2 năm nhưng tôi nghĩ tôi sẽ chia sẻ những gì tôi biết và hy vọng sẽ giảm bớt phần nào nỗi đau cho độc giả trong tương lai. Hoàn toàn minh bạch- Tôi hoàn toàn không phải là chuyên gia về Keycloak / OAuth / OIDC và những gì tôi biết chủ yếu là từ việc đọc tài liệu, sách, hay trên YouTube và chơi với công cụ này.
Bài đăng này sẽ bao gồm hai phần:
- Tôi sẽ cố gắng trả lời tất cả các câu hỏi của bạn trong khả năng tốt nhất của tôi
- Tôi sẽ chỉ cho bạn tất cả cách bạn có thể sử dụng các chính sách / phạm vi / quyền trong Keycloak mà không cần triển khai một ứng dụng riêng biệt để hiểu rõ hơn một số khái niệm cốt lõi trong chuỗi này. Xin lưu ý rằng điều này chủ yếu là để giúp bạn bắt đầu. Tôi đang sử dụng
Keycloak 8.0.0.
Phần I
Một số thuật ngữ trước khi chúng ta bắt đầu:
- Trong Keycloak, bạn có thể tạo 2 loại quyền: dựa vào tài nguyên và Phạm vi-Based .
- Nói một cách đơn giản, đối với
Resource-Basedquyền, bạn áp dụng nó trực tiếp vào tài nguyên của mình
- Đối với
Scoped-Basedquyền, bạn áp dụng nó cho (các) phạm vi hoặc (các) phạm vi và tài nguyên của bạn.
cách tốt nhất là chỉ tạo một phạm vi "chế độ xem" và sử dụng nó trên nhiều tài nguyên (tài khoản, giao dịch, v.v.)? Hay tôi nên tạo phạm vi "viewAccount", phạm vi "viewTransaction", v.v.?
Phạm vi đại diện cho một tập hợp các quyền tại một tài nguyên được bảo vệ. Trong trường hợp của bạn, bạn có 2 tài nguyên: accountvà transaction, vì vậy tôi sẽ nghiêng về cách tiếp cận thứ hai.
Về lâu dài, có một thế giới viewphạm vi liên quan đến mọi nguồn lực của bạn (ví dụ như account, transaction, customer,settlement ...) làm cho phép khó khăn cho cả quản lý và thích ứng với những thay đổi yêu cầu an ninh.
Dưới đây là một vài ví dụ mà bạn có thể xem qua để cảm nhận về thiết kế
Tuy nhiên, hãy lưu ý - tôi không tuyên bố rằng bạn không nên chia sẻ phạm vi giữa các tài nguyên. Vấn đề thực tế, Keycloakcho phép điều này đối với các tài nguyên giống nhau type. Ví dụ, bạn có thể cần cả hai viewAccountvà viewTransactionphạm vi để đọc một giao dịch trong một tài khoản nhất định (sau cùng, bạn có thể cần quyền truy cập vào tài khoản để xem các giao dịch). Yêu cầu và tiêu chuẩn của bạn sẽ ảnh hưởng rất nhiều đến thiết kế của bạn.
Đối với mỗi sự kết hợp thực tế của tài nguyên và phạm vi, thông thường bạn có tạo một quyền không?
Xin lỗi, tôi không hiểu hết câu hỏi nên tôi sẽ nói rộng hơn một chút. Để cấp / từ chối quyền truy cập vào a resource, bạn cần:
- Xác định các chính sách của bạn
- Xác định quyền của bạn
- Áp dụng các chính sách của bạn cho các quyền của bạn
- Liên kết các quyền của bạn với một
scopehoặc resource(hoặc cả hai)
để việc thực thi chính sách có hiệu lực. Xem Quy trình cấp phép .
Cách bạn thiết lập tất cả những điều này là hoàn toàn tùy thuộc vào bạn. Ví dụ, bạn có thể:
Xác định các chính sách riêng lẻ và ràng buộc từng chính sách dưới sự cho phép thích hợp.
Tốt hơn, hãy xác định các chính sách riêng lẻ, sau đó nhóm tất cả các chính sách có liên quan của bạn theo một aggregatedchính sách (một chính sách của các chính sách) và sau đó kết hợp chính sách tổng hợp đó với sự scope-basedcho phép. Bạn có thể có scoped-basedquyền đó áp dụng cho cả tài nguyên và tất cả phạm vi liên quan của nó.
Hoặc, bạn có thể chia nhỏ các quyền của mình hơn nữa bằng cách tận dụng hai loại riêng biệt. Bạn chỉ có thể tạo các quyền cho tài nguyên của mình thông qua resource-basedloại quyền và liên kết riêng các quyền khác chỉ với một phạm vi thông qua scope-basedloại quyền.
Bạn có các tùy chọn.
Nếu có nhiều quyền phù hợp với một tài nguyên / phạm vi nhất định, Keycloak sẽ làm gì?
Điều này phụ thuộc vào
- Máy chủ tài nguyên của
Decision Strategy
- Mỗi quyền của
Decision Strategy
LogicGiá trị của từng chính sách .
Các Logicgiá trị cũng tương tự như với Java của !nhà điều hành. Nó có thể là Positivehoặc Negative. Khi Logiclà Positive, đánh giá cuối cùng của chính sách vẫn không thay đổi. Khi mình Negative, kết quả cuối cùng là phủ nhận (ví dụ nếu một đánh giá lại chính sách sai lầm và nó Logiclà Negative, sau đó nó sẽ được true). Để giữ mọi thứ đơn giản, hãy giả sử rằng Logicluôn được đặt thành Positive.
Các Decision Strategylà những gì chúng ta thực sự muốn giải quyết. Có Decision Strategythể là Unanimoushoặc Affirmative. Từ các tài liệu,
Chiến lược quyết định
Cấu hình này thay đổi cách công cụ đánh giá chính sách quyết định có nên cấp tài nguyên hoặc phạm vi hay không dựa trên kết quả từ tất cả các quyền được đánh giá. Khẳng định có nghĩa là ít nhất một quyền phải đánh giá một quyết định tích cực để cấp quyền truy cập vào tài nguyên và phạm vi của nó. Nhất trí có nghĩa là tất cả các quyền phải đánh giá đến một quyết định tích cực để quyết định cuối cùng cũng tích cực. Ví dụ: nếu hai quyền cho cùng một tài nguyên hoặc phạm vi xung đột (một trong hai quyền đang cấp quyền truy cập và quyền kia từ chối quyền truy cập), quyền đối với tài nguyên hoặc phạm vi sẽ được cấp nếu chiến lược đã chọn là Khẳng định. Nếu không, một lần từ chối bất kỳ quyền nào cũng sẽ từ chối quyền truy cập vào tài nguyên hoặc phạm vi.
Hãy sử dụng một ví dụ để hiểu rõ hơn ở trên. Giả sử bạn có một tài nguyên với 2 quyền và ai đó đang cố gắng truy cập vào tài nguyên đó (hãy nhớ, đó Logiclà quyền Positivecho tất cả các chính sách). Hiện nay:
Permission Onecó một Decision Strategybộ để Affirmative. Nó cũng có 3 chính sách mà mỗi chính sách đánh giá:
Vì một trong các chính sách được đặt thành true, Permission Oneđược đặt thành true(Khẳng định - chỉ cần 1 true).
Permission Twocó một Decision Strategybộ Unanimousvới 2 chính sách:
Trong trường hợp Permission Twonày là falsevì một chính sách là sai (Nhất trí - tất cả đều cần phải như vậy true).
- Bây giờ đến đánh giá cuối cùng . Nếu máy chủ tài nguyên của
Decision Strategyđược đặt thành Affirmative, quyền truy cập vào tài nguyên đó sẽ được cấp vì Permission Onelà như vậy true. Mặt khác, nếu máy chủ tài nguyên Decision Strategyđược đặt thành Unanimous, quyền truy cập sẽ bị từ chối.
Xem:
Chúng tôi sẽ tiếp tục xem lại điều này. Tôi giải thích cách đặt máy chủ tài nguyên Decision Strategy trong Phần II.
vì vậy, ví dụ: tôi có thể có quyền truy cập vào "tài khoản" và quyền đối với phạm vi "xem", vì vậy tôi sẽ có quyền xem tài khoản?
Câu trả lời ngắn gọn là có. Bây giờ, hãy mở rộng vấn đề này một chút :)
Nếu bạn gặp trường hợp sau:
- Máy chủ tài nguyên
Decision Strategyđược đặt thành UnanimoushoặcAffirmative
- Quyền truy cập
account/{id}tài nguyên làtrue
- Quyền truy cập
viewphạm vi làtrue
Bạn sẽ được cấp quyền truy cập để xem tài khoản.
true+ truebằng với truedưới dấu Affirmativehoặc Unanimous Decision Strategy.
Bây giờ nếu bạn có cái này
- Máy chủ tài nguyên
Decision Strategyđược đặt thànhAffirmative
- Quyền truy cập
account/{id}tài nguyên làtrue
- Quyền truy cập
viewphạm vi làfalse
Bạn cũng sẽ được cấp quyền truy cập để xem tài khoản.
true+ falseLà truedưới Affirmativechiến lược.
Vấn đề ở đây là quyền truy cập vào một tài nguyên nhất định cũng phụ thuộc vào thiết lập của bạn, vì vậy hãy cẩn thận vì bạn có thể không muốn gặp trường hợp thứ hai.
Nhưng tôi nói đúng rằng điều này có nghĩa là tôi cần một chính sách cho từng nhóm kế thừa mà người dùng có thể thuộc về?
Tôi không chắc Keycloak đã hoạt động như thế nào cách đây 2 năm, nhưng bạn có thể chỉ định chính sách Dựa trên nhóm và chỉ cần thêm tất cả các nhóm của bạn theo chính sách đó. Bạn chắc chắn không cần tạo một chính sách cho mỗi nhóm.
Ví dụ: nếu tôi có vai trò "bộ phận trợ giúp", thì tôi cần chính sách "tư cách thành viên bộ phận trợ giúp", sau đó tôi có thể thêm chính sách này vào quyền "viewAccount". Điều này có chính xác?
Khá nhiều. Có nhiều cách bạn có thể thiết lập điều này. Ví dụ, bạn có thể:
- Tạo tài nguyên của bạn (ví dụ
/account/{id}) và liên kết nó với account:viewphạm vi.
- tạo Chính sách dựa trên
helpdesk vai trò và thêm vai trò theo chính sách đó
- Tạo một
Scope-Basedquyền được gọi viewAccountvà gắn nó với scope, resourcevàpolicy
Chúng tôi sẽ thiết lập một cái gì đó tương tự trong Phần II.
Phần II
Keycloak có một công cụ nhỏ gọn gàng cho phép bạn kiểm tra tất cả các chính sách của mình. Tốt hơn nữa, bạn thực sự không cần phải khởi động một máy chủ ứng dụng khác và triển khai một ứng dụng riêng để nó hoạt động.
Đây là kịch bản mà chúng tôi sẽ thiết lập:
- Chúng tôi sẽ tạo ra một lĩnh vực mới được gọi là
stackoverflow-demo
- Chúng tôi sẽ tạo một
bank-apikhách hàng trong lĩnh vực đó
- Chúng tôi sẽ xác định một tài nguyên được gọi
/account/{id}cho khách hàng đó
- Ý
account/{id}chí có account:viewphạm vi
- Chúng tôi sẽ tạo một người dùng được gọi
bobtrong lĩnh vực mới
- Chúng tôi cũng sẽ tạo ra ba vai trò:
bank_teller, account_ownervàuser
- Chúng tôi sẽ không liên kết
bobvới bất kỳ vai trò nào. Điều này là không cần thiết ngay bây giờ.
- Chúng tôi sẽ thiết lập hai
Role-Basedchính sách sau:
bank_tellervà account_ownercó quyền truy cập vào /account/{id}tài nguyên
account_ownercó quyền truy cập vào account:viewphạm vi
user không có quyền truy cập vào tài nguyên hoặc phạm vi
- Chúng tôi sẽ thử với
Evaluatecông cụ này để xem cách cấp hoặc từ chối quyền truy cập.
Hãy tha thứ cho tôi, ví dụ này là không thực tế nhưng tôi không quen thuộc với lĩnh vực ngân hàng :)
Thiết lập móc khóa
Tải xuống và chạy Keycloak
cd tmp
wget https://downloads.jboss.org/keycloak/8.0.0/keycloak-8.0.0.zip
unzip keycloak-8.0.0.zip
cd keycloak-8.0.0/bin
./standalone.sh
Tạo người dùng quản trị ban đầu
- Đi đến
http://localhost:8080/auth
- Bấm vào
Administration Console liên kết
- Tạo người dùng quản trị và đăng nhập
Truy cập Bắt đầu để biết thêm thông tin. Đối với mục đích của chúng tôi, những điều trên là đủ.
Thiết lập sân khấu
Tạo một lĩnh vực mới
- Di chuột xung quanh
mastervương quốc và nhấp vàoAdd Realm nút.
- Đi vào
stackoverflow-demo như tên.
- Bấm vào
Create .
- Trên cùng bên trái bây giờ nên nói
stackoverflow-demothay vì mastercảnh giới.
Xem Tạo một Vương quốc Mới
Tạo người dùng mới
- Nhấp vào
Usersliên kết bên trái
- Bấm vào
Add Usernút
- Nhập
username(ví dụ bob)
- Đảm bảo rằng
User Enabledđã bật
- Nhấp chuột
Save
Xem Tạo người dùng mới
Tạo vai trò mới
- Bấm vào
Rolesliên kết
- Bấm vào
Add Role
- Thêm các vai trò sau:
bank_teller, account_ownervàuser
Một lần nữa, không liên kết người dùng của bạn với các vai trò. Đối với mục đích của chúng tôi, điều này là không cần thiết.
Xem vai trò
Tạo khách hàng
- Bấm vào
Clientsliên kết
- Bấm vào
Create
- Nhập
bank-apichoClient ID
- Để
Root URLnhậphttp://127.0.0.1:8080/bank-api
- Bấm vào
Save
- Đảm bảo rằng
Client Protocollàopenid-connect
- Thay đổi
Access Typethànhconfidential
- Thay đổi
Authorization EnabledthànhOn
- Cuộn xuống và nhấn
Save. Một mớiAuthorization tab sẽ xuất hiện ở trên cùng.
- Nhấp vào
Authorizationtab và sau đóSettings
- Đảm bảo rằng
Decision Strategythiết lập được đặt thànhUnanimous
- Đây là máy chủ tài nguyên của
Decision Strategy
Xem:
Tạo phạm vi tùy chỉnh
- Bấm vào
Authorizationtab
- Bấm vào
Authorization Scopes> Createđể hiển thị Add Scopetrang
- Nhập
account:viewtên và nhấn Enter.
Tạo "Xem tài nguyên tài khoản"
- Bấm vào
Authorizationliên kết trên
- Bấm vào
Resources
- Bấm vào
Create
- Nhập
View Account Resourcecho cả NamevàDisplay name
- Nhập
account/{id}choURI
- Nhập
account:viewvào Scopeshộp văn bản
- Nhấp chuột
Save
Xem Tạo tài nguyên
Tạo chính sách của bạn
- Một lần nữa trong
Authorizationtab, nhấp vàoPolicies
- Chọn
RoletừCreate Policy menu thả xuống
- Trong
Namephần này, hãy nhậpOnly Bank Teller and Account Owner Policy
- Dưới
Realm Roleschọn cả vai trò bank_tellervàaccount_owner
- Đảm bảo rằng
Logicđược đặt thànhPositive
- Nhấp chuột
Save
- Bấm vào
Policies liên kết
- Chọn
Rolelại từ Create Policymenu thả xuống.
- Thời gian này sử dụng
Only Account Owner PolicychoName
- Dưới
Realm Roleslựa chọnaccount_owner
- Đảm bảo rằng
Logicđược đặt thànhPositive
- Nhấp chuột
Save
- Nhấp vào
Policiesliên kết ở trên cùng, bây giờ bạn sẽ thấy các chính sách mới được tạo của mình.
Xem Chính sách dựa trên vai trò
Xin lưu ý rằng Keycloak có nhiều chính sách mạnh mẽ hơn. Xem Chính sách Quản lý
Tạo quyền dựa trên tài nguyên
- Một lần nữa trong
Authorizationtab, nhấp vàoPermissions
- Lựa chọn
Resource-Based
- Nhập
View Account Resource PermissionchoName
- Dưới
ResourcesloạiView Account Resource Permission
- Dưới
Apply Policylựa chọnOnly Bank Teller and Account Owner Policy
- Đảm bảo rằng
Decision Strategythiết lập được đặt thànhUnanimous
- Nhấp chuột
Save
Xem Tạo quyền dựa trên tài nguyên
Phù ...
Đánh giá quyền dựa trên tài nguyên
- Một lần nữa trong
Authorizationtab, hãy chọnEvaluate
- Dưới
Usernhậpbob
- Dưới
Roleslựa chọnuser
- Đây là nơi chúng tôi sẽ liên kết người dùng của mình với các vai trò đã tạo của chúng tôi.
- Dưới
Resourceschọn View Account Resourcevà nhấpAdd
- Nhấp vào Đánh giá.
- Mở rộng
View Account Resource with scopes [account:view]để xem kết quả và bạn sẽ thấy DENY.

- Điều này có ý nghĩa vì chúng tôi chỉ cho phép hai vai trò truy cập vào tài nguyên đó thông qua
Only Bank Teller and Account Owner Policy. Hãy kiểm tra điều này để đảm bảo điều này là đúng!
- Nhấp vào
Backliên kết ngay trên kết quả đánh giá
- Thay đổi vai trò của bob thành
account_ownervà nhấp vào Evaluate. Bây giờ bạn sẽ thấy kết quả là PERMIT. Thỏa thuận tương tự nếu bạn quay lại và thay đổi vai trò thànhbank_teller
Xem Chính sách Đánh giá và Kiểm tra
Tạo quyền dựa trên phạm vi
- Quay lại
Permissionsphần
- Chọn
Scope-Basedthời gian này trong Create Permissionmenu thả xuống.
- Dưới
Name, nhậpView Account Scope Permission
- Dưới
Scopes, nhậpaccount:view
- Dưới
Apply Policy, nhậpOnly Account Owner Policy
- Đảm bảo rằng
Decision Strategythiết lập được đặt thànhUnanimous
- Nhấp chuột
Save
Xem Tạo quyền dựa trên phạm vi
Lần chạy thử thứ hai
Đánh giá những thay đổi mới của chúng tôi
- Quay lại
Authorizationphần
- Bấm vào
Evaluate
- Người dùng nên
bob
- Vai trò nên được
bank_teller
- Tài nguyên nên được
View Account Resourcevà nhấp vàoAdd
- Nhấp vào
Evaluatevà chúng ta sẽ nhận được DENY.
- Một lần nữa, điều này sẽ không có gì ngạc nhiên khi
bank_tellercó quyền truy cập vào resourcenhưng không phải scope. Ở đây một quyền đánh giá là true và quyền kia là false. Cho rằng máy chủ tài nguyên Decision Strategyđược đặt thành Unanimous, quyết định cuối cùng là DENY.
- Nhấp vào
Settingsbên dưới Authorizationtab và thay đổi Decision Strategythành Affirmativevà quay lại các bước 1-6 một lần nữa. Lần này, kết quả cuối cùng sẽ là PERMIT(một sự cho phép là đúng, vì vậy quyết định cuối cùng là đúng).
- Để hoàn thiện, hãy chuyển máy chủ tài nguyên
Decision Strategytrở lại Unanimous. Một lần nữa, quay lại các bước từ 1 đến 6 nhưng lần này, đặt vai trò là account_owner. Lần này, kết quả cuối cùng một lần nữa PERMITcó ý nghĩa, vì nó account_ownercó quyền truy cập vào cả resourcevà scope.
Gọn gàng :) Hy vọng điều này sẽ giúp.