Перейти к основному содержимому

Пользовательские атрибуты пользователя с Keycloak

· 5 мин. чтения

1. Обзор

Keycloak — это сторонний сервер авторизации, который управляет пользователями наших веб-приложений или мобильных приложений.

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

В этом руководстве мы увидим, как мы можем добавить пользовательские атрибуты пользователя на наш сервер авторизации Keycloak и получить к ним доступ в бэкэнде на основе Spring .

Сначала мы увидим это для автономного сервера Keycloak, а затем для встроенного .

2. Автономный сервер

2.1. Добавление пользовательских атрибутов пользователя

Первый шаг здесь — перейти в консоль администратора Keycloak. Для этого нам нужно запустить сервер, выполнив эту команду из папки bin нашего дистрибутива Keycloak :

./standalone.sh -Djboss.socket.binding.port-offset=100

Затем нам нужно перейти в консоль администратора и ввести учетные данные initial1 / zaq1!QAZ .

Затем мы нажмем « Пользователи » на вкладке « Управление », а затем « Просмотреть всех пользователей » :

./780fa5fba6578696c6962dd53b4045a0.png

Здесь мы видим пользователя, которого мы добавили ранее : user1 .

Теперь давайте нажмем на его ID и перейдем на вкладку Атрибуты , чтобы добавить новый, DOB для даты рождения:

./8ce41b15891be30a7895c44b1a2eba79.png

После нажатия кнопки « Сохранить » настраиваемый атрибут добавляется к информации о пользователе.

Затем нам нужно добавить сопоставление для этого атрибута в качестве пользовательского утверждения, чтобы оно было доступно в полезной нагрузке JSON для токена пользователя.

Для этого нам нужно перейти к клиенту нашего приложения в консоли администратора. Напомним, ранее мы создали клиент, login-app :

./355f58fc6660edd2b815454752d49273.png

Теперь давайте щелкнем по нему и перейдем на вкладку Mappers , чтобы создать новое сопоставление:

./08b0bf40d0ba6577cd2ba1d86cc07238.png

Сначала мы выберем Mapper Type как User Attribute , а затем установим Name , User Attribute и Token Claim Name как DOB . Утверждение типа JSON должно быть установлено как String .

Нажав Сохранить , наше сопоставление готово. Итак, теперь мы оснащены со стороны Keycloak для получения DOB в качестве пользовательского атрибута пользователя.

В следующем разделе мы увидим, как получить к нему доступ через вызов API .

2.2. Доступ к пользовательским атрибутам пользователя

Опираясь на наше приложение Spring Boot , давайте добавим новый контроллер REST, чтобы получить добавленный нами атрибут пользователя:

@Controller
public class CustomUserAttrController {

@GetMapping(path = "/users")
public String getUserInfo(Model model) {
KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken)
SecurityContextHolder.getContext().getAuthentication();

Principal principal = (Principal) authentication.getPrincipal();
String dob="";

if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal kPrincipal = (KeycloakPrincipal) principal;
IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();

Map<String, Object> customClaims = token.getOtherClaims();

if (customClaims.containsKey("DOB")) {
dob = String.valueOf(customClaims.get("DOB"));
}
}

model.addAttribute("username", principal.getName());
model.addAttribute("dob", dob);
return "userInfo";
}
}

Как мы видим, здесь мы сначала получили KeycloakAuthenticationToken из контекста безопасности, а затем извлекли из него принципала . Приведя его как KeycloakPrincipal , мы получили его IDToken .

Затем DOB можно извлечь из OtherClaims этого IDToken . ``

Вот шаблон с именем userInfo.html, который мы будем использовать для отображения этой информации:

<div id="container">
<h1>Hello, <span th:text="${username}">--name--</span>.</h1>
<h3>Your Date of Birth as per our records is <span th:text="${dob}"/>.</h3>
</div>

2.3. Тестирование

При запуске приложения Boot мы должны перейти по адресу http://localhost:8081/users . Сначала нас попросят ввести учетные данные.

После ввода учетных данных user1 мы должны увидеть эту страницу:

./d6b9d82e66fc753bfa7bb175bb45fbd3.png

3. Встроенный сервер

Теперь давайте посмотрим, как добиться того же на встроенном экземпляре Keycloak.

3.1. Добавление пользовательских атрибутов пользователя

По сути, нам нужно выполнить те же шаги здесь, только нам нужно будет сохранить их как предварительные конфигурации в нашем файле определения области, foreach-realm.json .

Чтобы добавить атрибут DOB нашему пользователю john@test.com , сначала нам нужно настроить его атрибуты:

"attributes" : {
"DOB" : "1984-07-01"
},

Затем добавьте преобразователь протокола для DOB :

"protocolMappers": [
{
"id": "c5237a00-d3ea-4e87-9caf-5146b02d1a15",
"name": "DOB",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"userinfo.token.claim": "true",
"user.attribute": "DOB",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "DOB",
"jsonType.label": "String"
}
}
]

Это все, что нам здесь нужно.

Теперь, когда мы рассмотрели часть добавления пользовательского атрибута пользователя сервером авторизации, пришло время посмотреть, как сервер ресурсов может получить доступ к DOB пользователя .

3.2. Доступ к пользовательским атрибутам пользователя

На стороне сервера ресурсов настраиваемые атрибуты будут просто доступны нам как значения утверждений в AuthenticationPrincipal .

Давайте напишем для него API:

@RestController
public class CustomUserAttrController {
@GetMapping("/user/info/custom")
public Map<String, Object> getUserInfo(@AuthenticationPrincipal Jwt principal) {
return Collections.singletonMap("DOB", principal.getClaimAsString("DOB"));
}
}

3.3. Тестирование

Теперь давайте проверим это с помощью JUnit.

Сначала нам нужно получить токен доступа, а затем вызвать конечную точку /user/info/custom API на сервере ресурсов:

@Test
public void givenUserWithReadScope_whenGetUserInformationResource_thenSuccess() {
String accessToken = obtainAccessToken("read");
Response response = RestAssured.given()
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)
.get(userInfoResourceUrl);

assertThat(response.as(Map.class)).containsEntry("DOB", "1984-07-01");
}

Как мы видим, здесь мы убедились, что получаем то же значение DOB , которое мы добавили в атрибуты пользователя .

4. Вывод

В этом уроке **мы узнали, как добавить дополнительные атрибуты пользователю в Keycloak.

**

Мы видели это как для автономного, так и для встроенного экземпляра. Мы также увидели, как получить доступ к этим пользовательским утверждениям в REST API на серверной части в обоих сценариях.

Как всегда, исходный код доступен на GitHub. Для автономного сервера — на GitHub с руководствами , а для встроенного экземпляра — на GitHub для OAuth .