1. Identity Brokering — Khái niệm
Identity Brokering cho phép Keycloak đóng vai trò trung gian xác thực giữa ứng dụng và các Identity Providers (IdP) bên ngoài. Thay vì mỗi ứng dụng tự tích hợp với Google, Facebook, SAML IdP riêng, tất cả đều kết nối qua Keycloak.
┌──────────┐ ┌──────────────┐ ┌──────────────────┐
│ My App │ ──→ │ Keycloak │ ──→ │ External IdP │
│ │ ←── │ (Broker) │ ←── │ (Google, SAML) │
└──────────┘ └──────────────┘ └──────────────────┘
Flow:
1. User truy cập My App → redirect đến Keycloak
2. User chọn "Login with Google" trên Keycloak login page
3. Keycloak redirect đến Google OAuth2
4. User xác thực tại Google → redirect về Keycloak
5. Keycloak nhận identity, tạo/link user, issue token
6. User redirect về My App với Keycloak token
Lợi ích:
- Centralized: Cấu hình IdP 1 lần tại Keycloak, tất cả apps đều dùng được
- Protocol bridging: App dùng OIDC, external IdP dùng SAML → Keycloak bridge
- User management: Keycloak quản lý tập trung, kể cả users từ external IdP
- Account linking: Link nhiều external identities vào 1 Keycloak account
2. Cấu hình Social Login
2.1 General Identity Provider Settings
Khi thêm bất kỳ IdP nào, các settings chung bao gồm:
| Setting | Mô tả | Giá trị |
|---|---|---|
| Alias | Identifier duy nhất cho IdP trong Keycloak | google, facebook |
| Display Name | Tên hiển thị trên login page | Google, Đăng nhập bằng Facebook |
| Enabled | Bật/tắt IdP | On |
| Hide on Login Page | Ẩn khỏi login page (chỉ dùng qua kc_idp_hint) | Off |
| Store Tokens | Lưu access token từ external IdP | Off (bật nếu cần gọi API external) |
| Stored Tokens Readable | User có thể đọc stored tokens | Off |
| Trust Email | Trust email từ IdP (không cần verify lại) | On cho Google/Microsoft |
| Account Linking Only | Chỉ dùng để link account, không cho tạo mới | Off |
| First Login Flow | Flow xử lý lần đầu đăng nhập | First Broker Login |
| Post Login Flow | Flow chạy sau mỗi lần đăng nhập qua IdP | None |
| Sync Mode | Đồng bộ user attributes | import, force, hoặc legacy |
2.2 Google OAuth2
Bước 1: Tạo OAuth2 Credentials tại Google
- Truy cập Google Cloud Console → APIs & Services → Credentials
- Click "Create Credentials → OAuth Client ID"
- Application type: Web application
- Name:
Keycloak Login - Authorized redirect URIs:
https://keycloak.example.com/realms/myrealm/broker/google/endpoint - Copy Client ID và Client Secret
Bước 2: Cấu hình trong Keycloak
- Vào Identity Providers → Add provider → Google
- Nhập:
- Client ID:
123456789.apps.googleusercontent.com - Client Secret:
GOCSPX-xxxxxxxxxxxx - Default Scopes:
openid profile email - Trust Email:
On— Google đã verify email - Sync Mode:
import
- Client ID:
- Save
Redirect URI format:
https://{keycloak-host}/realms/{realm}/broker/{alias}/endpoint
2.3 Facebook
Bước 1: Tạo Facebook App
- Truy cập Meta for Developers → My Apps → Create App
- App type: Consumer hoặc Business
- Thêm product "Facebook Login"
- Settings:
- Valid OAuth Redirect URIs:
https://keycloak.example.com/realms/myrealm/broker/facebook/endpoint
- Valid OAuth Redirect URIs:
- Copy App ID và App Secret
Bước 2: Cấu hình trong Keycloak
- Vào Identity Providers → Add provider → Facebook
- Nhập:
- Client ID: App ID
- Client Secret: App Secret
- Default Scopes:
email public_profile - Trust Email:
Off— Facebook cho phép email chưa verify
2.4 GitHub
Bước 1: Tạo GitHub OAuth App
- Truy cập GitHub → Settings → Developer Settings → OAuth Apps → New
- Application name:
Keycloak Login - Homepage URL:
https://myapp.example.com - Authorization callback URL:
https://keycloak.example.com/realms/myrealm/broker/github/endpoint - Copy Client ID và generate Client Secret
Bước 2: Cấu hình trong Keycloak
- Vào Identity Providers → Add provider → GitHub
- Nhập:
- Client ID: GitHub Client ID
- Client Secret: GitHub Client Secret
- Default Scopes:
user:email read:org(thêmread:orgnếu cần org info)
2.5 Apple Sign In
Bước 1: Cấu hình tại Apple Developer
- Truy cập Apple Developer → Certificates, Identifiers & Profiles
- Tạo App ID với Sign In with Apple capability
- Tạo Services ID:
- Identifier:
com.example.keycloak.login - Return URLs:
https://keycloak.example.com/realms/myrealm/broker/apple/endpoint
- Identifier:
- Tạo Key cho Sign In with Apple → download
.p8file
Bước 2: Cấu hình trong Keycloak
- Vào Identity Providers → Add provider → Apple
- Nhập:
- Client ID: Services ID (com.example.keycloak.login)
- Client Secret: Generated JWT từ .p8 key
- Default Scopes:
name email - Trust Email:
On
⚠️ Lưu ý Apple: Apple yêu cầu Client Secret là JWT signed với .p8 key, và JWT này hết hạn sau 6 tháng. Bạn cần refresh Client Secret định kỳ hoặc sử dụng script tự động.
2.6 Microsoft (Azure AD / Entra ID)
Bước 1: Đăng ký App trong Azure
- Truy cập Azure Portal → Microsoft Entra ID → App registrations → New
- Name:
Keycloak SSO - Supported account types: chọn phù hợp
Accounts in this organizational directory only— Single tenantAccounts in any organizational directory— Multi-tenantAccounts in any organizational directory and personal— Bao gồm cả @outlook.com
- Redirect URI:
Web→https://keycloak.example.com/realms/myrealm/broker/microsoft/endpoint - Vào Certificates & secrets → New client secret → copy value
Bước 2: Cấu hình trong Keycloak
- Vào Identity Providers → Add provider → Microsoft
- Nhập:
- Client ID: Application (client) ID
- Client Secret: Client secret value
- Default Scopes:
openid profile email - Trust Email:
On - Tenant: Nhập Tenant ID cho single-tenant, hoặc
commoncho multi-tenant
3. OpenID Connect Identity Providers
Ngoài social providers có sẵn, Keycloak hỗ trợ kết nối với bất kỳ OIDC provider nào.
3.1 Thêm OpenID Connect v1.0 Provider
- Vào Identity Providers → Add provider → OpenID Connect v1.0
- Cấu hình:
- Alias:
corporate-sso - Display Name:
Corporate SSO - Discovery Endpoint:
https://sso.corp.example.com/.well-known/openid-configuration - Hoặc nhập manual:
- Authorization URL:
https://sso.corp.example.com/authorize - Token URL:
https://sso.corp.example.com/token - User Info URL:
https://sso.corp.example.com/userinfo - JWKS URL:
https://sso.corp.example.com/jwks
- Authorization URL:
- Client ID: ID đã đăng ký tại external IdP
- Client Secret: Secret tương ứng
- Client Authentication:
Client secret sent as posthoặcClient secret sent as basic auth
- Alias:
Discovery Endpoint cho phép Keycloak tự động fetch tất cả URLs và capabilities của external IdP.
3.2 Keycloak-to-Keycloak Identity Brokering
Kết nối 2 Keycloak instances:
# Keycloak A (IdP) — Realm: company-a
Discovery: https://keycloak-a.example.com/realms/company-a/.well-known/openid-configuration
# Keycloak B (Broker) — Realm: main
# Thêm OIDC IdP với:
# - Discovery Endpoint: https://keycloak-a.example.com/realms/company-a/.well-known/openid-configuration
# - Client ID: registered in company-a realm
# - Client Secret: from company-a client
# Tại Keycloak A, tạo client cho Keycloak B:
# - Client ID: keycloak-b-broker
# - Valid Redirect URIs: https://keycloak-b.example.com/realms/main/broker/company-a/endpoint
# - Client Authentication: On
# - Standard Flow: Enabled
4. SAML 2.0 Identity Providers
4.1 Thêm SAML IdP
- Vào Identity Providers → Add provider → SAML v2.0
- Cấu hình:
- Alias:
corporate-saml - Import from URL: Nhập metadata URL của external SAML IdP
https://saml-idp.example.com/metadata - Hoặc Import from file: Upload XML metadata file
- Hoặc nhập manual:
- Single Sign-On Service URL:
https://saml-idp.example.com/sso - Single Logout Service URL:
https://saml-idp.example.com/slo - NameID Policy Format:
EmailhoặcPersistent - Want AuthnRequests Signed:
On - Want Assertions Signed:
On - Want Assertions Encrypted:
Off - Validate Signature:
On - Validating X509 Certificates: Paste IdP signing certificate
- Single Sign-On Service URL:
- Alias:
4.2 Keycloak SAML SP Metadata
External SAML IdP cần metadata của Keycloak (acting as Service Provider):
# Keycloak SP Descriptor URL
https://keycloak.example.com/realms/myrealm/broker/corporate-saml/endpoint/descriptor
# Đây là XML metadata chứa:
# - EntityID
# - AssertionConsumerService URL
# - SingleLogoutService URL
# - Keycloak signing certificate
5. OAuth v2 Identity Providers
Cho các providers chỉ hỗ trợ OAuth 2.0 (không có OIDC):
- Vào Identity Providers → Add provider → OAuth v2.0
- Cấu hình:
- Authorization URL: OAuth2 authorize endpoint
- Token URL: OAuth2 token endpoint
- User Info URL: Endpoint trả về user info (nếu có)
- Client ID / Client Secret
- User Info JSON Path: JSONPath để extract user attributes
# Ví dụ: nếu user info response là { "data": { "id": 123, "username": "john" } } # Username JSONPath: $.data.username # Email JSONPath: $.data.email
6. Kubernetes Identity Providers
Keycloak có thể hoạt động như IdP cho Kubernetes, và ngược lại có thể nhận identity từ Kubernetes.
6.1 Kubernetes OpenID Connect Provider
# Kubernetes API server config — sử dụng Keycloak làm IdP
apiVersion: v1
kind: Config
clusters:
- cluster:
server: https://k8s-api.example.com
certificate-authority: /etc/kubernetes/pki/ca.crt
name: my-cluster
users:
- name: oidc-user
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=https://keycloak.example.com/realms/myrealm
- --oidc-client-id=kubernetes
- --oidc-extra-scope=groups
# kube-apiserver flags cho OIDC authentication
--oidc-issuer-url=https://keycloak.example.com/realms/myrealm
--oidc-client-id=kubernetes
--oidc-username-claim=preferred_username
--oidc-groups-claim=groups
--oidc-ca-file=/etc/kubernetes/pki/keycloak-ca.crt
7. First Login Flow
First Login Flow xử lý lần đầu tiên user đăng nhập qua external IdP. Flow này quyết định:
- Có tạo user mới trong Keycloak không?
- Có link với user hiện tại không?
- Có yêu cầu review/update profile không?
7.1 Default First Broker Login Flow
First Broker Login Flow (mặc định)
├── Review Profile (Required) → Hiển thị profile để user review
│ └── Config: Update Profile on First Login = missing
└── User Creation or Linking (Required) → Sub-flow
├── Create User If Unique (Alternative) → Tạo user nếu email/username chưa tồn tại
└── Handle Existing Account (Alternative) → Sub-flow xử lý account đã tồn tại
├── Confirm Link Existing Account (Required) → Hỏi user có muốn link?
└── Verification (Alternative) → Sub-flow verify ownership
├── Verify Existing Account by Email (Alternative) → Gửi email verify
└── Verify Existing Account by Re-authentication (Alternative) → Nhập password
7.2 Cách hoạt động chi tiết
Scenario 1: User mới hoàn toàn
- User đăng nhập qua Google lần đầu
- Review Profile: Hiển thị profile (email, name) từ Google để user xác nhận
- Create User If Unique: Email chưa tồn tại → tạo Keycloak user mới
- Link Google identity với Keycloak user
- Đăng nhập thành công
Scenario 2: Email đã tồn tại trong Keycloak
- User đăng nhập qua GitHub, email
[email protected] - Create User If Unique: Email đã tồn tại → fail → chuyển sang alternative
- Confirm Link Existing Account: Hỏi "Account [email protected] đã tồn tại. Bạn muốn link?"
- Verify ownership: User verify bằng email HOẶC nhập password Keycloak
- Link GitHub identity với existing Keycloak user
7.3 Custom First Login Flow
Ví dụ: Auto-link account theo email không cần verify (chỉ dùng khi trust external IdP):
Auto-link First Login Flow
├── Create User If Unique (Alternative)
└── Automatically Set Existing User (Alternative) ← Tự link, không hỏi user
⚠️ Cảnh báo bảo mật:
Automatically Set Existing Userchỉ nên dùng khi bạn hoàn toàn tin tưởng external IdP. Nếu IdP cho phép tự do đặt email, attacker có thể chiếm account bằng cách đăng ký email người khác.
8. Account Linking
Account Linking cho phép user liên kết nhiều external identities vào 1 Keycloak account.
8.1 Linking qua Account Console
User có thể tự link/unlink trong Account Console:
https://keycloak.example.com/realms/myrealm/account/#/security/linked-accounts
8.2 Linking qua Application Initiated Action (AIA)
# Trigger account linking từ application
GET /realms/myrealm/protocol/openid-connect/auth?
client_id=my-app&
redirect_uri=https://myapp.example.com/callback&
response_type=code&
scope=openid&
kc_action=oidc-link&
kc_action_parameter=google
8.3 Linking qua Admin REST API
# Xem federated identities của user
curl -s -X GET \
"https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/federated-identity" \
-H "Authorization: Bearer $ADMIN_TOKEN" | jq
# Response
[
{
"identityProvider": "google",
"userId": "google-user-id-123",
"userName": "[email protected]"
}
]
# Thêm federated identity cho user
curl -X POST \
"https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/federated-identity/github" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"identityProvider": "github",
"userId": "github-user-id-456",
"userName": "johndoe"
}'
# Xóa federated identity
curl -X DELETE \
"https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/federated-identity/github" \
-H "Authorization: Bearer $ADMIN_TOKEN"
9. Identity Provider Mappers
IdP Mappers cho phép transform và map attributes từ external IdP sang Keycloak user attributes, roles, hoặc groups.
9.1 Mapper Types
| Mapper | Mô tả | Ví dụ |
|---|---|---|
| Attribute Importer | Import attribute từ IdP claim sang Keycloak user attribute | IdP picture → Keycloak avatar_url |
| Hardcoded Role | Gán role cố định cho tất cả users từ IdP | Tất cả Google users → role external-user |
| Hardcoded Group | Gán group cố định | Tất cả GitHub users → group /external/github |
| Username Template Importer | Tạo username từ template | ${ALIAS}.${CLAIM.preferred_username} |
| External Role to Role | Map external IdP role sang Keycloak role | SAML role admin → Keycloak role realm-admin |
| Hardcoded Attribute | Set attribute cố định cho users từ IdP | source=google cho tất cả Google users |
| SAML Attribute to Role | Map SAML assertion attribute sang Keycloak role | SAML department=IT → role it-team |
| Advanced Claim to Role | Map claim phức tạp (JSON path, regex) sang role | Claim groups contains "admins" → role admin |
9.2 Cấu hình Mappers
Ví dụ 1: Attribute Importer — Import avatar từ Google
- Vào Identity Providers → Google → Mappers → Add mapper
- Cấu hình:
- Name:
Import Avatar URL - Mapper Type:
Attribute Importer - Claim:
picture(claim name từ Google) - User Attribute Name:
avatar_url(Keycloak user attribute) - Sync Mode Override:
inherit
- Name:
Ví dụ 2: Hardcoded Role — Gán role cho external users
- Vào Identity Providers → GitHub → Mappers → Add mapper
- Cấu hình:
- Name:
Assign External User Role - Mapper Type:
Hardcoded Role - Role:
external-user
- Name:
Ví dụ 3: Username Template — Prefix username với IdP alias
- Cấu hình:
- Mapper Type:
Username Template Importer - Template:
${ALIAS}.${CLAIM.preferred_username} - Target:
LOCAL
- Mapper Type:
- Kết quả: user từ Google sẽ có username =
google.john.doe
Ví dụ 4: External Role to Role — Map SAML roles
- Cấu hình:
- Mapper Type:
External Role to Role - External Role:
admin(role name từ external SAML IdP) - Role:
realm-admin(Keycloak role)
- Mapper Type:
10. Sync Modes
Sync Mode kiểm soát cách Keycloak đồng bộ thông tin từ external IdP mỗi lần user đăng nhập.
| Mode | First Login | Subsequent Logins | Use case |
|---|---|---|---|
| import | Import attributes từ IdP | Không cập nhật — giữ nguyên data Keycloak | User có thể chỉnh profile trong Keycloak |
| force | Import attributes từ IdP | Luôn overwrite với data mới từ IdP | IdP là source of truth tuyệt đối |
| legacy | Import attributes từ IdP | Cập nhật nếu attribute trống, giữ nguyên nếu đã có | Tương thích backward, merge data |
Cấu hình Sync Mode:
- Ở IdP level: Áp dụng cho tất cả mappers của IdP đó
- Ở Mapper level (Sync Mode Override): Override sync mode cho mapper cụ thể
# Ví dụ: Google IdP với sync mode = import
# Mapper "Import Avatar" với Sync Mode Override = force
# Kết quả:
# - Email, name: import 1 lần, user có thể sửa trong Keycloak
# - Avatar URL: luôn cập nhật từ Google (force)
11. Client-suggested IdP (kc_idp_hint)
kc_idp_hint cho phép ứng dụng tự động redirect user đến external IdP cụ thể, bỏ qua Keycloak login page.
11.1 Sử dụng kc_idp_hint
# Redirect trực tiếp đến Google login
GET /realms/myrealm/protocol/openid-connect/auth?
client_id=my-app&
redirect_uri=https://myapp.example.com/callback&
response_type=code&
scope=openid&
kc_idp_hint=google
# Redirect trực tiếp đến SAML IdP
GET /realms/myrealm/protocol/openid-connect/auth?
client_id=my-app&
redirect_uri=https://myapp.example.com/callback&
response_type=code&
scope=openid&
kc_idp_hint=corporate-saml
JavaScript integration:
// keycloak-js adapter
const keycloak = new Keycloak({
url: 'https://keycloak.example.com',
realm: 'myrealm',
clientId: 'my-app'
});
// Đăng nhập qua Google
function loginWithGoogle() {
keycloak.login({
idpHint: 'google'
});
}
// Đăng nhập qua corporate SAML
function loginWithCorporate() {
keycloak.login({
idpHint: 'corporate-saml'
});
}
11.2 Identity Provider Redirector trong Browser Flow
Identity Provider Redirector dalam Browser Flow tự động xử lý kc_idp_hint:
- Nếu request có
kc_idp_hint=google→ redirect ngay đến Google - Nếu không có hint → tiếp tục flow bình thường (hiển thị login page)
Default IdP: Bạn có thể set default IdP cho Identity Provider Redirector — khi không có hint, tự redirect đến IdP mặc định:
- Click ⚙️ bên cạnh
Identity Provider Redirector - Nhập Default Identity Provider:
google
12. Identity Broker Logout
Khi user logout khỏi Keycloak, bạn có thể cấu hình để propagate logout đến external IdP.
12.1 Backchannel Logout
Keycloak hỗ trợ backchannel logout với external OIDC IdP:
- Trong OIDC IdP configuration, enable Backchannel Logout
- External IdP phải hỗ trợ backchannel logout endpoint
- Khi user logout khỏi Keycloak → Keycloak gửi logout request đến external IdP
Cho SAML IdP, logout propagation được xử lý qua SAML Single Logout (SLO) protocol tự động.
13. Multiple Instances of Same Social Broker
Keycloak cho phép thêm nhiều instances của cùng một social provider, mỗi cái với alias khác nhau:
# Ví dụ: 2 Google IdPs cho 2 Google Workspace domains
Identity Providers:
- Alias: google-corp → Google Workspace domain corp.example.com
- Alias: google-partner → Google Workspace domain partner.example.com
# Mỗi instance có Client ID / Client Secret riêng
# registered tại Google Cloud Console khác nhau
Cách thêm:
- Thêm OIDC v1.0 provider (không dùng built-in Google provider cho instance thứ 2)
- Alias:
google-partner - Discovery Endpoint:
https://accounts.google.com/.well-known/openid-configuration - Client ID / Secret: credentials riêng cho instance thứ 2
14. Hiện/Ẩn IdPs trong Account Console
Kiểm soát user có thể thấy và link/unlink IdP nào trong Account Console:
- Hiện trên Login page: Không tick
Hide on Login Page - Ẩn khỏi Login page: Tick
Hide on Login Page— vẫn dùng được quakc_idp_hint - Hiện trong Account Console: IdP mặc định hiện trong Linked Accounts
- Account Linking Only: IdP chỉ hiện trong Account Console, không hiện ở Login page
15. Tóm tắt
| Khái niệm | Mô tả |
|---|---|
| Identity Brokering | Keycloak làm trung gian giữa apps và external IdPs |
| Social Login | Google, Facebook, GitHub, Apple, Microsoft |
| OIDC/SAML/OAuth2 IdP | Kết nối bất kỳ IdP nào theo protocol standards |
| First Login Flow | Xử lý lần đầu: tạo user mới hoặc link existing |
| Account Linking | Link nhiều external identities vào 1 Keycloak account |
| IdP Mappers | Transform attributes: Attribute Importer, Hardcoded Role/Group, Username Template |
| Sync Modes | import (1 lần), force (luôn overwrite), legacy (merge) |
| kc_idp_hint | Skip login page, redirect thẳng đến IdP cụ thể |
| Broker Logout | Propagate logout đến external IdP (backchannel/SLO) |