知識庫 / Spring / Spring Boot RSS 訂閱

使用 Keycloak 定製用户屬性

Security,Spring Boot
HongKong
4
12:46 PM · Dec 06 ,2025

1. 概述

Keycloak 是我們 Web 或移動應用程序的用户授權服務器。

它提供了一些默認屬性,例如名字、姓氏和電子郵件,用於存儲任何給定用户的屬性。 但在許多情況下,這些屬性可能不足,我們需要為我們的應用程序添加一些特定的用户屬性。

在本教程中,我們將學習如何將自定義用户屬性添加到 Keycloak 授權服務器,並在基於 Spring 的後端中訪問它們

首先,我們將針對獨立的 Keycloak 服務器進行演示,然後針對嵌入式 Keycloak 服務器進行演示。

2. 獨立服務器

2.1. 添加自定義用户屬性

首先,請前往 Keycloak 的管理控制枱。為此,我們需要從 Keycloak 分發的 bin 文件夾中運行該命令啓動服務器:

kc.bat start-dev

然後我們需要前往 管理控制枱,並輸入 initial1/zaq1!QAZ 憑據。

接下來,我們點擊“用户”選項卡下的 用户

在這裏我們可以看到我們之前添加的用户:user1

現在,我們點擊其 ID 並前往“屬性”選項卡,以添加一個新的屬性,DOB 表示出生日期:

點擊“保存”後,自定義屬性將被添加到用户的資料中。

接下來,我們需要為該屬性創建一個映射,作為自定義聲明,以便在用户令牌的 JSON 負載中可用。

為此,我們需要前往應用程序客户端在管理控制枱中的設置。 之前我們創建的客户端是 login-app

clients

現在,點擊它,然後點擊“客户端範圍”選項卡。 在“客户端範圍”頁面點擊 login-app-dedicated 鏈接並前往其“映射器”選項卡。 現在點擊“配置新的映射器”並選擇“用户屬性”以創建新的映射:

設置“名稱”、“用户屬性”和“令牌名稱”為 DOB。 “聲明 JSON 類型”應設置為 字符串

點擊“保存”後,我們的映射已就緒。 因此,我們現在可以從 Keycloak 端接收 DOB 作為自定義用户屬性。

在下一部分中,我們將看到如何通過 API 調用訪問它

2.2. 訪問自定義用户屬性

在基於我們的 Spring Boot 應用程序的基礎上,讓我們添加一個新的 REST 控制器來獲取我們添加的用户的屬性:

@Controller
public class CustomUserAttrController {

    @GetMapping(path = "/users")
    public String getUserInfo(Model model) {

        final DefaultOidcUser user = (DefaultOidcUser) SecurityContextHolder.getContext()
            .getAuthentication()
            .getPrincipal();

        String dob = "";

        OidcIdToken token = user.getIdToken();

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

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

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

}

如我們所見,首先我們從安全上下文中獲取了 身份驗證,然後從中提取了 OidcUser。 接下來,我們可以從該 OidcUser 中獲取其 IDToken DOB,這些信息可以從該 IDToken 的 Claims 中提取。

以下是用於顯示這些信息的模板,名為 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 的憑據後,您將看到以下頁面:

3. 內嵌服務器

現在讓我們看看如何在內嵌 Keycloak 實例上實現相同的功能。

3.1. 添加自定義用户屬性

基本上,我們需要執行相同的步驟,只是我們需要將它們保存為 realm 定義文件中預配置項,即 baeldung-realm.json

為了將屬性 DOB 添加到用户 [email protected] 中,首先我們需要配置其屬性:

"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"
        }
    }
]

這就是我們需要的全部內容。

現在我們已經瞭解了自定義用户屬性添加中授權服務器的部分,接下來我們來探討資源服務器如何訪問用户的出生日期

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</em/> 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 在後端訪問這些自定義聲明。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.