Найти в Дзене
Wissance

Добавляем информацию о пользователе в Keycloak: настраиваем роли

OpenId, KeyCloak и атрибуты пользователя Одним из широко используемых стандартов аутентификации является OpenId, он является достаточно простым и удобным. Авторизация очень проста: { "sub": "46db60cb-73f0-4722-947d-2c7815cab1d2", "email_verified": false, "name": "firstTestName lastTestName", "preferred_username": "testuser", "given_name": "firstTestName", "family_name": "lastTestName", "email": "testuser@testdomain.com" } Если нам нужно проверить, что у пользователя правильная пара логин + пароль, такая схема подойдет и больше ничего не нужно, здесь мы получаем, что аутентификация == авторизация. Но если ситуация усложняется тем, что не все пользователи одинаково полезны могут выполнять одинаковые действия (аутентификацяи != авторизация), то нам нужно как-то отличать их, на основе каких-то атрибутов или свойств, привязанных к самим пользователям. И эта информация должна храниться на сервере авторизации. Для таких целей применяют авторизацию на основе ролей, т.к. пользова
Оглавление

OpenId, KeyCloak и атрибуты пользователя

Одним из широко используемых стандартов аутентификации является OpenId, он является достаточно простым и удобным. Авторизация очень проста:

  1. Получаем токен используя endpoint для получения токена (этот эндпоинт отличается URL у разных серверов, например для Keycloak он выглядит так: http://123.123.10.10:8080/auth/realms/master/protocol/openid-connect/token (в данном случае это пример,
  2. Прикрепляем полученный токен к запросу через заголовок `Authorization` `Bearer {token}`, где {token} - полученный на шаге 1 токен
  3. В большинстве самых простых случаев нам достаточно в приложении проверить, что токен, который, отправлен в п. 2 валидный и, что он не истек, для этого мы дергаем эндпоинт /userinfo (например, http://123.123.10.10:8080/auth/realms/master/protocol/openid-connect/userinfo) и получаем информацию о пользователе в виде:
{
"sub": "46db60cb-73f0-4722-947d-2c7815cab1d2",
"email_verified": false,
"name": "firstTestName lastTestName",
"preferred_username": "testuser",
"given_name": "firstTestName",
"family_name": "lastTestName",
"email": "testuser@testdomain.com"
}

Если нам нужно проверить, что у пользователя правильная пара логин + пароль, такая схема подойдет и больше ничего не нужно, здесь мы получаем, что аутентификация == авторизация. Но если ситуация усложняется тем, что не все пользователи одинаково полезны могут выполнять одинаковые действия (аутентификацяи != авторизация), то нам нужно как-то отличать их, на основе каких-то атрибутов или свойств, привязанных к самим пользователям. И эта информация должна храниться на сервере авторизации. Для таких целей применяют авторизацию на основе ролей, т.к. пользователей может быть очень много и им достаточно назначить правильные роли, а приложения уже сами будут решать, что могут делать пользователи в зависимости от их набора ролей.

Keycloak является одним из решений для аутентфикации и авторизации пользователей, мы используем его в своих проектах, т.к. он достаточно простой в установке и настройке и обладает хорошим набором возможностей, таких как:

  • интеграция внешних провайдеров (Google, Facebook, Github и др.)
  • позволяет использовать LDAP для получения списка пользователей
  • позволяет обогащать пользователей разными дополнительными атрибутами и свойствами

В качестве примера использования KeyCloak с NetCore Web API (REST)-приложением, можно рассмотреть нашу библиотеку (будем признательны если вы поставите звездочку на github).

Настраиваем роли

Теперь, перейдем к практической части. Мы предполагаем, что наш читатель уже предварительно настроил KeyCloak (если нужен такой туториал пиши в комментариях, при наличии 100 лайков мы выпустим такой туториал), а именно:

  • Создал Realm
  • Создал клиента в этом Realm'е
  • Создал одного или нескольких тестовых пользователей

Также в рамках данного туториала мы будем рассматривать самы простой способ настройки:

  • Роли не будут обладать какой-то сложной структурой, роль - строка с именем роли;
  • Мы будем создавать роль, привязанную к клиенту, мы не будем подтягивать роли из Active Directory и т.п.

Теперь когда мы обозначили граничные условия переходим к описанию того, как это сделать:

1. Внутри клиента нам потребуется создать mapper с типом User Client Role:

процедура создания mapper'а
процедура создания mapper'а

Создадим роль client_test_role в ролях пользователя:

создаем роль
создаем роль

Для тестов возьмем пользователя (у нас уже есть один - testuser) и присвоим ему роль:

Роль назначена
Роль назначена

Теперь можем перейти к проверке, для этого можно запросить эндпоинт userinfo или воспользоваться встроенным механизмом оценки возвращаемого результата.

Как посмотреть, что вернет Keycloak без использования клиента и т.п.

Мы можем проверять, что для данного клиента возвращается в userinfo не вызывая каким-либо из HTTP-клиентов эндпоинта Keycloak. Для этого мы должны перейти в меню Client Scopes и действовать по алгоритму, показанному на изображении:

Выбираем тестового пользователя и нажимаем Evaluate
Выбираем тестового пользователя и нажимаем Evaluate

Далее переходим на вкладку Generated User Info

Теперь мы можем посмотреть, что будет возвращено в userinfo для пользователя testuser
Теперь мы можем посмотреть, что будет возвращено в userinfo для пользователя testuser

Как видно из изображения мы успешно создали mapper, роль на уровне клиента и присоединили эту роль к пользователю testuser.

Заключение

В заключении можно сказать, что мы рассмотрели достаточно простой способ добавления ролей к информации о пользователе в эндпоинт userinfo, но при этом этот способ позволяет различать пользователей и настраивать авторизацию должным образом. Спасибо, что дочитали, просьба поддержать нас лайком и подпиской.