1. Обзор
Keycloak — это система управления идентификацией и доступом (IAM) с открытым исходным кодом, которая хорошо интегрируется с приложением Spring Boot. В этом руководстве мы опишем, как получить идентификатор пользователя Keycloak в приложении Spring Boot.
2. Постановка задачи
Keycloak предоставляет такие функции, как защита REST API, федерация пользователей, тонкая авторизация, вход через социальные сети, двухфакторная аутентификация (2FA) и т. д. Кроме того, мы можем использовать его для реализации единого входа ( SSO ) с использованием OpenID Connect ( ОИДК ). Предположим, что у нас есть приложение Spring Boot, защищенное OIDC с помощью Keycloak, и мы хотим получить идентификатор пользователя в приложении Spring Boot. В этой ситуации нам потребуется получить токен доступа или контекст безопасности в приложении Spring Boot.
2.1. Keycloak Server как сервер авторизации
Для простоты мы будем использовать Keycloak, встроенный в приложение Spring Boot . Предположим, что мы используем проект сервера авторизации, доступный на GitHub . Во-первых, мы определим клиент customerClient
в области foreach
на нашем встроенном сервере Keycloak:
затем мы экспортируем сведения о области как customer-realm.json
и установим файл области в нашем application-customer.yml
:
keycloak:
server:
contextPath: /auth
adminUser:
username: bael-admin
password: pass
realmImportFile: customer-realm.json
Наконец, мы можем запустить приложение, используя параметр –spring.profiles.active=customer
. Теперь сервер авторизации готов. После запуска сервера мы можем получить доступ к приветственной странице сервера авторизации по адресу http://localhost:8083/auth/.
2.2. Сервер ресурсов
Теперь, когда мы настроили сервер авторизации, давайте настроим сервер ресурсов. Для этого мы будем использовать проект сервера ресурсов, доступный на GitHub . Во-первых, давайте добавим файл application-embedded.properties
в качестве ресурса:
keycloak.auth-server-url=http://localhost:8083/auth
keycloak.realm=foreach
keycloak.resource=customerClient
keycloak.public-client=true
keycloak.principal-attribute=preferred_username
Теперь сервер ресурсов защищен с помощью сервера авторизации OAuth2, и мы должны войти на сервер единого входа, чтобы получить доступ к ресурсам. Мы можем запустить приложение, используя параметр –spring.profiles.active=embedded
.
3. Получите идентификатор пользователя Keycloak
Получить идентификатор пользователя из Keycloak можно несколькими способами: с помощью токена доступа или клиентского сопоставления.
3.1. По токену доступа
Основываясь на классе CustomUserAttrController
приложения Spring Boot , давайте изменим метод getUserInfo()
, чтобы получить идентификатор пользователя:
@GetMapping(path = "/users")
public String getUserInfo(Model model) {
KeycloakAuthenticationToken authentication =
(KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
Principal principal = (Principal) authentication.getPrincipal();
String userIdByToken = "";
if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal<KeycloakSecurityContext> kPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();
userIdByToken = token.getSubject();
}
model.addAttribute("userIDByToken", userIdByToken);
return "userInfo";
}
Как видим, сначала мы получили Principal
из класса KeycloakAuthenticationToken
. Затем мы извлекаем идентификатор пользователя из IDToken с помощью
метода getSubject()
.
3.2. По клиентскому картографу
Мы можем добавить идентификатор пользователя в сопоставитель клиента и получить его в приложении Spring Boot. Сначала мы определяем клиентский преобразователь в клиенте customerClient
:
Затем мы получаем идентификатор пользователя в классе CustomUserAttrController
:
@GetMapping(path = "/users")
public String getUserInfo(Model model) {
KeycloakAuthenticationToken authentication =
(KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
Principal principal = (Principal) authentication.getPrincipal();
String userIdByMapper = "";
if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal<KeycloakSecurityContext> kPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();
userIdByMapper = token.getOtherClaims().get("user_id").toString();
}
model.addAttribute("userIDByMapper", userIdByMapper);
return "userInfo";
}
Мы используем метод getOtherClaims()
из IDToken
для получения картографа. Затем мы добавляем идентификатор пользователя в атрибут модели.
3.3. Лист тимьяна
Мы изменим шаблон userInfo.html
для отображения информации об идентификаторе пользователя:
<div id="container">
<h1>
User ID By Token: <span th:text="${userIDByToken}">--userID--</span>.
</h1>
<h1>
User ID By Mapper: <span th:text="${userIDByMapper}">--userID--</span>.
</h1>
</div>
3.4. Тест
После запуска приложения мы можем перейти по адресу http://localhost:8081/users
. Ввод foreach:foreach
для учетных данных вернет следующее:
4. Вывод
В этой статье мы рассмотрели получение идентификатора пользователя из Keycloak в приложении Spring Boot. Сначала мы настраиваем необходимую среду для вызова защищенного приложения. Затем мы описали получение идентификатора пользователя Keycloak в приложении Spring Boot с использованием IDToken
и клиентского сопоставителя. Как всегда, полный исходный код этого руководства доступен на GitHub . Кроме того, исходный код сервера авторизации доступен на GitHub .