Chuyển đến nội dung chính

Lesson 12: Identity Brokering and Social Login

Identity Provider concept, Social Login configuration (Google, Facebook, GitHub, Apple, Microsoft), OpenID Connect Identity Providers, SAML Identity Providers, OAuth v2 providers, Kubernetes Identity Providers. First Login Flow, Account Linking, Identity Provider Mappers, Sync Mode (import, force, legacy), client-suggested IdP (kc_idp_hint) and IdP logout flow.

🔒 DevSecOps — Lesson 12 Lesson 12: Identity Brokering and Social Login

Keycloak from Basic to Advanced

Part 3: Authentication, MFA and Identity Brokering

xdev.asia

1. Identity Brokering — Concept

Identity Brokering allows Keycloak to act as authentication broker between the application and external Identity Providers (IdPs). Instead of each application integrating with its own Google, Facebook, SAML IdP, they all connect via 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

Benefits:

  • Centralized: Configure IdP once at Keycloak, all apps can use it
  • Protocol bridging: App uses OIDC, external IdP uses SAML → Keycloak bridge
  • User management: Keycloak centrally manages, including users from external IdP
  • Account linking: Link multiple external identities to 1 Keycloak account

2. Configure Social Login

2.1 General Identity Provider Settings

When adding any IdP, common settings include:

SettingDescriptionValue
AliasUnique Identifier for IdP in Keycloakgoogle, facebook
Display NameName displayed on login pageGoogle, Log in with Facebook
EnabledEnable/disable IdPOn
Hide on Login PageHide from login page (only use via kc_idp_hint)Off
Store TokensSave access token from external IdPOff (turn on if need to call external API)
Stored Tokens ReadableUser can read stored tokensOff
Trust EmailTrust email from IdP (no need to verify again)On for Google/Microsoft
Account Linking OnlyOnly used to link accounts, not allowed to create newOff
First Login FlowFlow handles first loginFirst Broker Login
Post Login FlowFlow runs after each login via IdPNone
Sync ModeSync user attributesimport, force, or legacy

2.2 Google OAuth2

Step 1: Create OAuth2 Credentials at Google

  1. Go to Google Cloud Console → APIs & Services → Credentials
  2. Click "Create Credentials → OAuth Client ID"
  3. Application type: Web application
  4. Name: Keycloak Login
  5. Authorized redirect URIs: https://keycloak.example.com/realms/myrealm/broker/google/endpoint
  6. Copy Client ID and Client Secret

Step 2: Configure in Keycloak

  1. Go to Identity Providers → Add provider → Google
  2. Enter:
    • Client ID: 123456789.apps.googleusercontent.com
    • Client Secret: GOCSPX-xxxxxxxxxxxx
    • Default Scopes: openid profile email
    • Trust Email: On — Google has verified email
    • Sync Mode: import
  3. Save

Redirect URI format:

https://{keycloak-host}/realms/{realm}/broker/{alias}/endpoint

2.3 Facebook

Bước 1: Tạo Facebook App

  1. Truy cập Meta for Developers → My Apps → Create App
  2. App type: Consumer hoặc Business
  3. Thêm product "Facebook Login"
  4. Settings:
    • Valid OAuth Redirect URIs: https://keycloak.example.com/realms/myrealm/broker/facebook/endpoint
  5. Copy App ID và App Secret

Bước 2: Cấu hình trong Keycloak

  1. Vào Identity Providers → Add provider → Facebook
  2. 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

  1. Truy cập GitHub → Settings → Developer Settings → OAuth Apps → New
  2. Application name: Keycloak Login
  3. Homepage URL: https://myapp.example.com
  4. Authorization callback URL: https://keycloak.example.com/realms/myrealm/broker/github/endpoint
  5. Copy Client ID và generate Client Secret

Bước 2: Cấu hình trong Keycloak

  1. Vào Identity Providers → Add provider → GitHub
  2. Nhập:
    • Client ID: GitHub Client ID
    • Client Secret: GitHub Client Secret
    • Default Scopes: user:email read:org (thêm read:org nếu cần org info)

2.5 Apple Sign In

Bước 1: Cấu hình tại Apple Developer

  1. Truy cập Apple Developer → Certificates, Identifiers & Profiles
  2. Tạo App ID với Sign In with Apple capability
  3. Tạo Services ID:
    • Identifier: com.example.keycloak.login
    • Return URLs: https://keycloak.example.com/realms/myrealm/broker/apple/endpoint
  4. Tạo Key cho Sign In with Apple → download .p8 file

Bước 2: Cấu hình trong Keycloak

  1. Vào Identity Providers → Add provider → Apple
  2. 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

  1. Truy cập Azure Portal → Microsoft Entra ID → App registrations → New
  2. Name: Keycloak SSO
  3. Supported account types: chọn phù hợp
    • Accounts in this organizational directory only — Single tenant
    • Accounts in any organizational directory — Multi-tenant
    • Accounts in any organizational directory and personal — Bao gồm cả @outlook.com
  4. Redirect URI: Web → https://keycloak.example.com/realms/myrealm/broker/microsoft/endpoint
  5. Vào Certificates & secrets → New client secret → copy value

Bước 2: Cấu hình trong Keycloak

  1. Vào Identity Providers → Add provider → Microsoft
  2. 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 common cho 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

  1. Vào Identity Providers → Add provider → OpenID Connect v1.0
  2. 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
    • Client ID: ID đã đăng ký tại external IdP
    • Client Secret: Secret tương ứng
    • Client Authentication: Client secret sent as post hoặc Client secret sent as basic auth

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 Add SAML IdP

  1. Go to Identity Providers → Add provider → SAML v2.0
  2. Configuration:
    • Alias: corporate-saml
    • Import from URL: Import metadata URL of 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: Email hoặc Persistent
      • Want AuthnRequests Signed: On
      • Want Assertions Signed: On
      • Want Assertions Encrypted: Off
      • Validate Signature: On
      • Validating X509 Certificates: Paste IdP signing certificate

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

For providers that only support OAuth 2.0 (no OIDC):

  1. Go to Identity Providers → Add provider → OAuth v2.0
  2. Configuration:
    • Authorization URL: OAuth2 authorize endpoint
    • Token URL: OAuth2 token endpoint
    • User Info URL: Endpoint returns user info (if any)
    • Client ID / Client Secret
    • User Info JSON Path: JSONPath to 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 can act as an IdP for Kubernetes, and vice versa can receive identity from 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 handles the first time user logs in via external IdP. This flow decides:

  • Can I create a new user in Keycloak?
  • Is there a link to the current user?
  • Is there a request to review/update profile?

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 Detailed operation

Scenario 1: Completely new user

  1. User logs in via Google for the first time
  2. Review Profile: Display profile (email, name) from Google for user to confirm
  3. Create User If Unique: Email does not exist → create new Keycloak user
  4. Link Google identity with Keycloak user
  5. Successful login

Scenario 2: Email already exists in Keycloak

  1. User logged in via GitHub, email [email protected]
  2. Create User If Unique: Email already exists → fail → switch to alternative
  3. Confirm Link Existing Account: Ask "Account [email protected] already exists. Do you want the link?"
  4. Verify ownership: User verify by email OR enter Keycloak password
  5. Link GitHub identity with existing Keycloak user

7.3 Custom First Login Flow

For example: Auto-link account by email no need to verify (only used when trusting external IdP):

Auto-link First Login Flow
├── Create User If Unique (Alternative)
└── Automatically Set Existing User (Alternative)   ← Tự link, không hỏi user

⚠️ Security warning: Automatically Set Existing User should only be used if you fully trust external IdP. If the IdP allows you to freely set emails, attackers can take over accounts by registering for other people's emails.

8. Account Linking

Account Linking allows users to link multiple external identities into one Keycloak account.

8.1 Linking qua Account Console

Users can link/unlink themselves in 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 allow transform and map attributes from external IdP to Keycloak user attributes, roles, or groups.

9.1 Mapper Types

MapperDescriptionExample
Attribute ImporterImport attribute from IdP claim to Keycloak user attributeIdP picture → Keycloak avatar_url
Hardcoded RoleAssign a fixed role to all users from IdPAll Google users → role external-user
Hardcoded GroupAssign fixed groupAll GitHub users → group /external/github
Username Template ImporterCreate username from template${ALIAS}.${CLAIM.preferred_username}
External Role to RoleMap external IdP role sang Keycloak roleSAML role admin → Keycloak role realm-admin
Hardcoded AttributeSet fixed attribute for users from IdPsource=google for all Google users
SAML Attribute to RoleMap SAML assertion attribute sang Keycloak roleSAML department=IT → role it-team
Advanced Claim to RoleMap complex claim (JSON path, regex) to roleClaim groups contains "admins" → role admin

9.2 Mappers Configuration

Example 1: Attribute Importer — Import avatar from Google

  1. Go to Identity Providers → Google → Mappers → Add mapper
  2. Configuration:
    • Name: Import Avatar URL
    • Mapper Type: Attribute Importer
    • Claim: picture (claim name from Google)
    • User Attribute Name: avatar_url (Keycloak user attribute)
    • Sync Mode Override: inherit

Example 2: Hardcoded Role — Assign role to external users

  1. Go to Identity Providers → GitHub → Mappers → Add mapper
  2. Configuration:
    • Name: Assign External User Role
    • Mapper Type: Hardcoded Role
    • Role: external-user

Example 3: Username Template — Prefix username with IdP alias

  1. Configuration:
    • Mapper Type: Username Template Importer
    • Template: ${ALIAS}.${CLAIM.preferred_username}
    • Target: LOCAL
  2. Result: user from Google will have username = google.john.doe

Example 4: External Role to Role — Map SAML roles

  1. Configuration:
    • Mapper Type: External Role to Role
    • External Role: admin (role name from external SAML IdP)
    • Role: realm-admin (Keycloak role)

10. Sync Modes

Sync Mode controls how Keycloak synchronizes information from external IdP each time a user logs in.

ModeFirst LoginSubsequent LoginsUse case
importImport attributes from IdPDo not update — keep data KeycloakUser can edit profile in Keycloak
forceImport attributes from IdPAlways overwrite with new data from IdPIdP is the source of absolute truth
legacyImport attributes from IdPUpdate if attribute is empty, keep if existingBackwards compatible, merge data

Configure Sync Mode:

  • At IdP level: Applies to all mappers of that IdP
  • At Mapper level (Sync Mode Override): Override sync mode for specific mapper
# 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 allows the application to automatically redirect users to a specific external IdP, bypassing the Keycloak login page.

11.1 Use 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 automatically handles kc_idp_hint:

  • If request has kc_idp_hint=google → immediately redirect to Google
  • If there is no hint → continue normal flow (display login page)

Default IdP: You can set default IdP for Identity Provider Redirector — when there is no hint, automatically redirect to the default IdP:

  1. Click ⚙️ next to Identity Provider Redirector
  2. Enter Default Identity Provider: google

12. Identity Broker Logout

When the user logs out from Keycloak, you can configure propagate logout to external IdP.

12.1 Backchannel Logout

Keycloak supports backchannel logout with external OIDC IdP:

  1. Trong OIDC IdP configuration, enable Backchannel Logout
  2. External IdP must support backchannel logout endpoint
  3. When user logs out from Keycloak → Keycloak sends logout request to external IdP

For SAML IdP, logout propagation is handled via the SAML Single Logout (SLO) protocol automatically.

13. Multiple Instances of Same Social Broker

Keycloak allows adding multiple instances of the same social provider, each with a different alias:

# 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:

  1. Add OIDC v1.0 provider (do not use the built-in Google provider for the 2nd instance)
  2. Alias: google-partner
  3. Discovery Endpoint: https://accounts.google.com/.well-known/openid-configuration
  4. Client ID / Secret: separate credentials for the 2nd instance

14. Show/Hide IdPs in Account Console

Controls which IdP users can see and link/unlink in Account Console:

  • Show on Login page: Unchecked Hide on Login Page
  • Hide from Login page: Tick Hide on Login Page — still available via kc_idp_hint
  • Show in Account Console: Default IdP shows in Linked Accounts
  • Account Linking Only: IdP only appears in Account Console, not on Login page

15. Summary

ConceptDescription
Identity BrokeringKeycloak mediates between apps and external IdPs
Social LoginGoogle, Facebook, GitHub, Apple, Microsoft
OIDC/SAML/OAuth2 IdPConnect any IdP according to protocol standards
First Login FlowFirst processing: create new user or existing link
Account LinkingLinking multiple external identities to 1 Keycloak account
IdP MappersTransform attributes: Attribute Importer, Hardcoded Role/Group, Username Template
Sync Modesimport (once), force (always overwrite), legacy (merge)
kc_idp_hintSkip login page, redirect straight to specific IdP
Broker LogoutPropagate logout to external IdP (backchannel/SLO)