Mendalami klaim OIDC dan profil user di Keycloak: klaim standar profile, email, alamat dan telepon, membuat klaim kustom lewat user attributes dan protocol mappers, serta strategi menyeimbangkan ID token dan UserInfo endpoint.

Di episode 9 kalian melihat ID token berisi klaim seperti name dan email. Episode 10 ini membuka kap mesin: dari mana klaim itu berasal, klaim standar apa saja yang ada, bagaimana menambahkan klaim kustom lewat user attributes dan protocol mappers, serta bagaimana memilih strategi — muat semua di token, atau ambil dari UserInfo endpoint.
OIDC mendefinisikan serangkaian klaim standar yang dibagi per kelompok:
name, given_name, family_name, picture, dan lainnya.email dan email_verified.address yang berisi formatted, street_address, locality, region, postal_code, dan country.phone_number dan phone_number_verified.Klaim-klaim ini dipetakan dari data user Keycloak oleh protocol mapper bawaan yang sudah menempel pada client scope profile, email, address, dan phone.
Data user di Keycloak tersimpan dalam dua lapis:
department atau employee_id.Atribut kustom ditambahkan di halaman user, lalu diangkat menjadi klaim lewat mapper:
{
"sub": "9c4d5e6f-...",
"preferred_username": "budi",
"department": "engineering",
"employee_id": "EMP-1042"
}Di atas, department dan employee_id adalah klaim kustom hasil mapping atribut user. Klaim ini kemudian bisa dibaca aplikasi untuk logika bisnis — misalnya menentukan menu yang muncul.
Protocol mapper adalah jembatan antara data Keycloak dan token. Keycloak menyediakan beberapa jenis mapper:
| Jenis mapper | Fungsi | Contoh hasil |
|---|---|---|
| User Attribute | Menyalin atribut user ke klaim | department |
| User Property | Menyalin properti bawaan user | locale, createdTimestamp |
| Client ID | Menulis identitas client | client_id sebagai klaim |
| Audience | Menambah aud token | audiens tambahan |
| Role | Memetakan role ke klaim | roles di realm_access |
| Group | Memetakan grup user | group membership |
| Hardcoded claim | Menyisipkan nilai tetap | env: production |
| JavaScript | Logika mapping kustom | transformasi bebas |
Mapper bisa ditempel di client scope (berlaku untuk semua client yang memakai scope itu) atau langsung di client (khusus client tersebut). Pilih client scope bila banyak client butuh klaim yang sama.
Dua mapper yang sering diabaikan padahal praktis:
"tier": "gold" untuk semua token dari satu client.firstName dan lastName menjadi display_name, atau mengubah format nomor.const fullName = user.getFirstName() + " " + user.getLastName();
token.setClaim("display_name", fullName);Gunakan JavaScript mapper dengan hati-hati dan hanya bila mapper bawaan tidak mencukupi — skrip yang salah bisa melambatkan token issuance atau memunculkan bug yang sulit dilacak.
Mapping klaim bukan hanya soal atribut. Empat pola mapping yang sering dipakai di produksi:
aud sehingga token bisa dipakai di lebih dari satu resource server, atau justru mempersempit audiens.Tiga jalur klaim yang berbeda, dengan konsekuensi berbeda pula:
| Aspek | ID Token | Access Token | UserInfo |
|---|---|---|---|
| Isi | Identitas user | Otorisasi dan roles | Profil sesuai scope |
| Pemakai | Aplikasi klien | Resource server | Aplikasi klien |
| Kekayaan klaim | Ringkas | Tergantung kebutuhan API | Bisa lebih lengkap |
| Efek ukuran | Membesar setiap klaim | Membesar setiap request | Tidak menyentuh token |
Untuk membaca profil lewat UserInfo, aplikasi cukup memanggil endpoint-nya dengan access token:
curl -s -H "Authorization: Bearer eyJhbGciOi..." \
"https://kc.example.com/realms/my-realm/protocol/openid-connect/userinfo"protocol/openid-connect/userinfo mengembalikan klaim yang diizinkan oleh scope yang disetujui user — kebalikan dari ID token yang isinya sudah terkunci sejak token diterbitkan.
Memilih di mana klaim ditempatkan adalah keputusan desain dengan tiga pertimbangan:
Ukuran juga biaya: token yang membengkak memperlambat request dan memboroskan memori. Aturan praktisnya, muat ke token hanya yang benar-benar dipakai setiap request; sisanya lewat UserInfo endpoint.
Warning
Klaim di dalam token tidak bisa ditarik kembali sebelum token kedaluwarsa. Jika user dipecat atau rolenya diubah, token lama yang masih hidup tetap membawa klaim lama. Karena itu jangan taruh keputusan keamanan yang berubah-ubah ke dalam token; taruh ke resource server yang bisa memeriksa status terbaru setiap request.
Episode 10 membahas klaim OIDC dan user profile: klaim standar dari profil hingga telepon, user attributes sebagai sumber data kustom, jenis-jenis protocol mappers termasuk hardcoded dan JavaScript mapper, pola claims mapping, serta strategi menyeimbangkan ID token, access token, dan UserInfo endpoint.
Inti yang harus dibawa pulang:
Di episode 11 berikutnya kalian akan belajar session management — bagaimana Keycloak melacak sesi login di banyak aplikasi sekaligus, bagaimana single logout bekerja, dan bagaimana memantau serta mencabut sesi dari admin console.