Я знаю, що запізнився на 2+ роки, але, думаю, поділюсь тим, що знаю, і, сподіваюся, полегшу біль для майбутніх читачів. Повна прозорість - я ні в якому разі не є експертом Keycloak / OAuth / OIDC, і те, що я знаю, здебільшого пов’язана з читанням документів, книг, хорошого старого YouTube та бажанням із інструментом.
Цей пост буде складатися з двох частин:
- Я спробую відповісти на всі ваші запитання, наскільки можу
- Я покажу вам усім, як ви можете пограти з політиками / сферами / дозволами в Keycloak без необхідності розгортати окремий додаток, щоб краще зрозуміти деякі основні концепції в цій темі. Хоча зауважте, що це в основному призначено для того, щоб ви все почали. Я використовую
Keycloak 8.0.0.
Частина І
Певна термінологія, перш ніж ми почнемо:
- У Keycloak ви можете створити 2 типи дозволів: на основі ресурсів та сфери дії .
- Простіше кажучи, для
Resource-Basedдозволів ви застосовуєте його безпосередньо до свого ресурсу
- Для отримання
Scoped-Basedдозволу ви застосовуєте його до своїх областей дії або сфери та ресурсу.
чи найкращою практикою є створення лише однієї сфери "перегляду" та використання її у кількох ресурсах (обліковий запис, транзакція тощо)? Або я повинен створити область "viewAccount", область "viewTransaction" тощо?
Сфери представляють сукупність прав на захищений ресурс. У вашому випадку у вас є 2 ресурси: accountі transaction, тому я б схилився до другого підходу.
У довгостроковій перспективі, маючи глобальний viewохоплення , пов'язаний з усіма ресурсами (наприклад account, transaction, customer, settlement...) робить дозвіл важко як управляти і адаптуватися до змін вимог безпеки.
Ось кілька прикладів, які ви можете переглянути, щоб відчути дизайн
Хоча зауважте - я не стверджую, що ви не повинні ділитися сферами використання між ресурсами. Справа в тому, Keycloakщо це дозволяє для ресурсів з однаковими type. Наприклад, вам може знадобитися і те, viewAccountі інше, viewTransactionщоб прочитати транзакцію за даним рахунком (адже вам може знадобитися доступ до облікового запису для перегляду транзакцій). Ваші вимоги та стандарти будуть сильно впливати на ваш дизайн.
Чи є звичайною практикою створення дозволу для кожної практичної комбінації ресурсу та обсягу?
Перепрошую, я не повністю розумію питання, тому буду трохи широким. Для того, щоб надати / заборонити доступ до resource, вам потрібно:
- Визначте свою політику
- Визначте свої дозволи
- Застосовуйте свою політику до своїх дозволів
- Прив’яжіть свої дозволи до
scopeабо resource(або обох)
для набрання чинності політикою. Див. Процес авторизації .
Як ви налаштовуєте все це, залежить лише від вас. Наприклад, ви можете:
Визначте окремі правила та пов'яжіть кожну політику з відповідним дозволом.
А ще краще, визначте окремі політики, потім згрупуйте всі пов’язані політики за aggregatedполітикою (політикою політик), а потім пов’яжіть цю агреговану політику з scope-basedдозволом. Ви можете мати такий scoped-basedдозвіл як на ресурс, так і на всю пов’язану з ним сферу застосування.
Або ви можете додатково розбити свої дозволи, використовуючи два окремі типи. Ви можете створювати дозволи виключно для своїх ресурсів за допомогою resource-basedтипу дозволу та окремо пов’язувати інші дозволи виключно із сферою застосування за допомогою scope-basedтипу дозволу.
У вас є варіанти.
Якщо для даного ресурсу / області дії існує кілька дозволів, що робить Keycloak?
Це залежить від
- Сервер ресурсів
Decision Strategy
- Кожен дозвіл
Decision Strategy
LogicЗначення кожної політики .
LogicЗначення аналогічно з Явою !оператором. Це може бути Positiveабо Negative. Коли Logicє Positive, остаточна оцінка політики залишається незмінною. Коли його Negative, кінцевий результат заперечується (наприклад, якщо політика оцінює як хибне і Logicє Negative, тоді воно буде true). Щоб все було простішим, припустимо, що Logicзавжди встановлено значення Positive.
Це Decision Strategyте, з чим ми справді хочемо боротися. Decision StrategyМоже бути або Unanimousабо Affirmative. З документів,
Стратегія прийняття рішень
Ця конфігурація змінює спосіб, яким механізм оцінки політики вирішує, чи слід надавати ресурс чи область на основі результатів усіх оцінених дозволів. Підтвердження означає, що принаймні один дозвіл повинен оцінюватись як позитивне рішення, щоб надати доступ до ресурсу та його сфери дії. Одностайне означає, що всі дозволи повинні оцінюватися як позитивне рішення, щоб остаточне рішення було також позитивним. Наприклад, якщо два дозволи для одного ресурсу або сфери конфлікту (один з них надає доступ, а інший забороняє доступ), дозвіл на ресурс або область буде надано, якщо обрана стратегія є Стверджувальною. В іншому випадку одне відмовлення будь-якого дозволу також забороняє доступ до ресурсу або сфери.
Давайте скористаємось прикладом, щоб краще зрозуміти вищесказане. Припустимо, у вас є ресурс із 2 дозволами, і хтось намагається отримати доступ до цього ресурсу (пам’ятайте, Logicце Positiveдля всіх політик). Зараз:
Permission Oneмає Decision Strategyнабір Affirmative. Він також має 3 політики, кожна з яких оцінює:
Оскільки для однієї з політик встановлено значення true, Permission Oneвстановлено значення true(Ствердно - має бути лише 1 true).
Permission Twoмає Decision Strategyнабір Unanimousіз 2 політиками:
У цьому випадку Permission Two, falseоскільки одна політика є хибною (одноголосною - усі вони повинні бути true).
- Тепер настає остаточне оцінювання. Якщо для сервера ресурсів
Decision Strategyвстановлено значення Affirmative, доступ до цього ресурсу буде наданий, оскільки Permission Oneє true. Якщо, з іншого боку, для сервера ресурсів Decision Strategyвстановлено значення Unanimous, доступ буде заборонено.
Подивитися:
Ми будемо продовжувати переглядати це. Я пояснюю, як встановити розділ ресурсу Decision Strategy в Частині II.
так, наприклад, я міг би мати дозвіл на доступ до "облікових записів" та дозвіл на область "перегляду", тому я мав би дозвіл на перегляд облікових записів?
Коротка відповідь - так. Тепер давайте трохи розширимо це :)
Якщо у вас такий сценарій:
- Для сервера ресурсів
Decision Strategyвстановлено значення UnanimousабоAffirmative
- Дозвіл на доступ до
account/{id}ресурсу єtrue
- Дозвіл на доступ до
viewгалузі єtrue
Вам буде надано доступ для перегляду облікового запису.
true+ trueдорівнює trueпід Affirmativeабо Unanimous Decision Strategy.
Тепер якщо у вас є це
- Для сервера ресурсів
Decision Strategyвстановлено значенняAffirmative
- Дозвіл на доступ до
account/{id}ресурсу єtrue
- Дозвіл на доступ до
viewгалузі єfalse
Вам також буде надано доступ для перегляду облікового запису.
true+ falseзнаходиться trueпід Affirmativeстратегією.
Справа в тому, що доступ до даного ресурсу також залежить від ваших налаштувань, тому будьте обережні, оскільки, можливо, ви не хочете другого сценарію.
Але чи я правий, що це означає, що мені потрібна політика щодо кожної зі застарілих груп, до якої міг належати користувач?
Я не впевнений, як поводився Keycloak 2 роки тому, але ви можете вказати групову політику та просто додати всі свої групи відповідно до цієї політики. Вам точно не потрібно створювати одну політику для кожної групи.
Наприклад, якщо у мене є роль "довідкової служби", то мені потрібна політика "членства довідкової служби", яку я потім можу додати до дозволу "viewAccount". Це правильно?
Доволі багато. Існує багато способів налаштувати це. Наприклад, ви можете:
- Створіть свій ресурс (наприклад
/account/{id}) і пов’яжіть його із account:viewсферою застосування.
- створити політику на основі ролей та додати
helpdeskроль відповідно до цієї політики
- Створіть
Scope-Basedдозвіл, який викликається, viewAccountі пов’яжіть його з scope, resourceтаpolicy
Ми створимо щось подібне в Частині II.
Частина ІІ
Keycloak має акуратний маленький інструмент, який дозволяє перевірити всі ваші правила. А ще краще - вам фактично не потрібно закручувати інший сервер додатків і розгортати окремий додаток, щоб це працювало.
Ось сценарій, який ми створимо:
- Ми створимо нову сферу під назвою
stackoverflow-demo
- Ми створимо
bank-apiклієнта в цій сфері
- Ми визначимо ресурс, покликаний
/account/{id}для цього клієнта
account/{id}Матиме account:viewобсяг
- Ми створимо користувача, якого називають
bobновим царством
- Ми також створимо три ролі:
bank_teller, account_ownerіuser
- Ми не будемо спілкуватися
bobз жодними ролями. Зараз це не потрібно.
- Ми встановимо наступні дві
Role-Basedполітики:
bank_tellerі account_ownerмати доступ до /account/{id}ресурсу
account_ownerмає доступ до account:viewсфери застосування
user не має доступу до ресурсу або сфери застосування
- Ми пограємо з
Evaluateінструментом, щоб побачити, як можна надати або заборонити доступ.
Вибачте мене, цей приклад нереальний, але я не знайомий з банківським сектором :)
Налаштування клавіатури
Завантажте та запустіть 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
Створити початкового користувача адміністратора
- Йти до
http://localhost:8080/auth
- Клацніть на
Administration Consoleпосилання
- Створіть користувача адміністратора та логін
Для отримання додаткової інформації відвідайте розділ Початок роботи . Для наших цілей достатньо зазначеного.
Встановлення сцени
Створіть нове царство
- Наведіть курсор миші на
masterобласть і натисніть на Add Realmкнопку.
- Введіть
stackoverflow-demoяк назву.
- Клацніть на
Create.
- Угорі ліворуч тепер слід писати
stackoverflow-demoзамість masterобласті.
Див. Створення нового царства
Створіть нового користувача
- Клацніть на
Usersпосилання зліва
- Клацніть на
Add Userкнопку
- Введіть
username(наприклад bob)
- Переконайтеся, що
User Enabledйого ввімкнено
- Клацніть
Save
Див. Розділ Створення нового користувача
Створюйте нові ролі
- Клацніть на
Rolesпосилання
- Натисніть на
Add Role
- Додайте наступні ролі:
bank_teller, account_ownerіuser
Знову ж таки, не пов’язуйте свого користувача з ролями. Для наших цілей це не потрібно.
Див. Ролі
Створіть клієнта
- Клацніть на
Clientsпосилання
- Натисніть на
Create
- Введіть
bank-apiдляClient ID
- Для
Root URLвходуhttp://127.0.0.1:8080/bank-api
- Натисніть на
Save
- Переконайтеся, що
Client Protocolце такopenid-connect
- Змініть
Access Typeнаconfidential
- Змінити
Authorization EnabledнаOn
- Прокрутіть вниз і натисніть
Save. AuthorizationУгорі повинна з’явитися нова вкладка.
- Клацніть на
Authorizationвкладці, а потімSettings
- Переконайтеся, що
Decision Strategyвстановлено значенняUnanimous
- Це сервер ресурсів
Decision Strategy
Подивитися:
Створюйте власні сфери
- Клацніть на
Authorizationвкладці
- Натисніть
Authorization Scopes>, Createщоб відкрити Add Scopeсторінку
- Введіть
account:viewім’я та натисніть Enter.
Створити "Переглянути ресурс облікового запису"
- Клацніть на
Authorizationпосилання вище
- Натисніть на
Resources
- Натисніть на
Create
- Введіть
View Account Resourceяк для, так Nameі дляDisplay name
- Введіть
account/{id}дляURI
- Введіть
account:viewу Scopesтекстовому полі
- Клацніть
Save
Див. Створення ресурсів
Створіть свою політику
- Знову під
Authorizationвкладкою натиснітьPolicies
- Виберіть
Roleзі Create Policyспадного меню
- У
Nameрозділі введітьOnly Bank Teller and Account Owner Policy
- У розділі
Realm Rolesвиберіть bank_tellerі account_ownerроль, і роль
- Переконайтеся, що
Logicвстановлено значенняPositive
- Клацніть
Save
- Клацніть на
Policiesпосилання
- Виберіть
Roleзнову зі Create Policyспадного меню.
- Цього разу використовуйте
Only Account Owner PolicyдляName
- Під
Realm Rolesвиберітьaccount_owner
- Переконайтеся, що
Logicвстановлено значенняPositive
- Клацніть
Save
- Клацніть на
Policiesпосилання у верхній частині, і тепер ви побачите свої новостворені правила.
Див. Рольову політику
Зверніть увагу, що Keycloak має набагато потужніші правила. Див. Управління політиками
Створення дозволу на основі ресурсів
- Знову під
Authorizationвкладкою натиснітьPermissions
- Виберіть
Resource-Based
- Введіть
View Account Resource PermissionдляName
- Під
ResourcesтипомView Account Resource Permission
- Під
Apply PolicyвиберітьOnly Bank Teller and Account Owner Policy
- Переконайтеся, що
Decision Strategyвстановлено значенняUnanimous
- Клацніть
Save
Див. Розділ Створення дозволів на основі ресурсів
Фу ...
Оцінка дозволу на основі ресурсів
- Знову під
Authorizationвкладкою виберітьEvaluate
- Під
Userenterbob
- Під
Rolesвиберітьuser
- Тут ми пов’яжемо нашого користувача зі своїми створеними ролями.
- Під
Resourcesвиберіть View Account Resourceі натиснітьAdd
- Клацніть на Оцінити.
- Розгорніть,
View Account Resource with scopes [account:view]щоб побачити результати, і ви повинні побачити DENY.

- Це має сенс, оскільки ми дозволяємо доступ до цього ресурсу лише двом ролям через
Only Bank Teller and Account Owner Policy. Давайте перевіримо це, щоб переконатися, що це правда!
- Клацніть на
Backпосилання прямо над результатом оцінки
- Змініть роль Бобу
account_ownerта натисніть на Evaluate. Тепер ви повинні бачити результат як PERMIT. Така ж угода, якщо ви повернетесь і зміните роль наbank_teller
Див. Оцінку та тестування політики
Створення дозволу на основі сфери дії
- Поверніться до
Permissionsрозділу
- Виберіть
Scope-Basedцей час у Create Permissionспадному меню.
- Під
Name, введітьView Account Scope Permission
- Під
Scopes, введітьaccount:view
- Під
Apply Policy, введітьOnly Account Owner Policy
- Переконайтеся, що
Decision Strategyвстановлено значенняUnanimous
- Клацніть
Save
Див. Розділ Створення дозволів на основі сфери дії
Другий пробний запуск
Оцінка наших нових змін
- Поверніться до
Authorizationрозділу
- Натисніть на
Evaluate
- Користувач повинен бути
bob
- Ролі повинні бути
bank_teller
- Ресурси повинні бути
View Account Resourceі клацнутиAdd
- Натисніть
Evaluateі ми повинні отримати DENY.
- Знову ж це не повинно дивувати, оскільки
bank_tellerмає доступ до, resourceале не scope. Тут один дозвіл оцінюється як істинний, а інший - як хибний. Враховуючи, що для сервера ресурсів Decision Strategyвстановлено значення Unanimous, остаточне рішення є DENY.
- Клацніть на
Settingsпід Authorizationвкладкою, змініть Decision Strategyна Affirmativeі знову поверніться до кроків 1-6. Цього разу повинен бути кінцевий результат PERMIT(один дозвіл відповідає дійсності, отже, остаточне рішення відповідає дійсності).
- Для повноти поверніть сервер ресурсів
Decision Strategyназад до Unanimous. Знову поверніться до кроків з 1 по 6, але цього разу встановіть роль як account_owner. Цього разу остаточний результат знову PERMITмає сенс, враховуючи те, що він account_ownerмає доступ як до, так resourceі до scope.
Акуратно :) Сподіваюся, це допомагає.