- Kiểm Tra Providers Đã Load
- Test Authenticator
- Test Protocol Mapper
- Test Event Listener
- Test REST API
- Test End-to-End
- Mở browser: http://localhost:8080
- Login với:
- Username:
admin - Password:
admin
- Username:
- Click Server Info ở menu bên trái (dưới cùng)
- Click tab Providers
- Tìm kiếm "federation" trong ô search
Bạn sẽ thấy các providers sau:
- Provider ID:
federation-hub - Class:
FederationHubResourceProviderFactory - Purpose: REST API endpoints cho quản lý IdP và routing rules
- Provider ID:
federation-partner-claims-mapper - Class:
PartnerClaimsMapperFactory - Purpose: Map claims từ federated IdP vào Keycloak token
- Provider ID:
federation-hub-authenticator - Class:
FederationHubAuthenticatorFactory - Purpose: Intelligent routing authenticator
- Provider ID:
federation-audit - Class:
FederationEventListenerProviderFactory - Purpose: Audit logging và event streaming
- Vào Authentication → Flows
- Click Create flow
- Nhập:
- Name:
Federation Hub Flow - Description:
Test flow for federation hub
- Name:
- Click Create
- Trong flow vừa tạo, click Add execution
- Tìm và chọn federation-hub-authenticator
- Click Add
- Set Requirement thành REQUIRED
- Click icon ⚙️ (Settings) bên cạnh authenticator
- Cấu hình các options (nếu có)
- Click Save
- Vào Realm Settings → Login
- Set Browser Flow thành
Federation Hub Flow - Logout và thử login lại
- Authenticator sẽ được trigger
- Vào Client Scopes
- Click Create client scope
- Nhập:
- Name:
federation-claims - Type:
Default
- Name:
- Click Save
- Trong client scope vừa tạo, vào tab Mappers
- Click Add mapper → By configuration
- Tìm và chọn federation-partner-claims-mapper
- Configure:
- Name:
partner-claims - Token Claim Name:
partner_info - Claim JSON Type:
JSON
- Name:
- Click Save
- Vào Clients → Chọn client (ví dụ:
admin-cli) - Vào tab Client Scopes
- Click Add client scope
- Chọn
federation-claims - Click Add → Default
- Get token mới:
$body = @{
username = "admin"
password = "admin"
grant_type = "password"
client_id = "admin-cli"
scope = "openid profile email"
}
$response = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/protocol/openid-connect/token" -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
# Decode token để xem claims
$token = $response.access_token
Write-Output $token- Decode token tại https://jwt.io để xem claims
- Vào Realm Settings → Events
- Click tab Event Listeners
- Tìm federation-audit trong dropdown
- Click Add để thêm vào danh sách
- Click Save
- Vào tab User events settings
- Enable Save events
- Chọn event types muốn log:
- Login
- Login Error
- Logout
- Register
- etc.
- Click Save
- Logout khỏi Admin Console
- Login lại
- Thử login sai password
- Logout
- Vào Events → Login events
- Xem các events đã được log
- Check logs:
docker logs keycloak-federation-hub | grep -i "federation.*event"$body = @{
username = "admin"
password = "admin"
grant_type = "password"
client_id = "admin-cli"
}
$response = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/protocol/openid-connect/token" -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
$token = $response.access_token
$headers = @{
"Authorization" = "Bearer $token"
"Content-Type" = "application/json"
}# List all IdPs
try {
$idps = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/federation-hub/idps" -Headers $headers -Method Get
Write-Output "Found $($idps.Count) IdPs"
$idps | ConvertTo-Json
} catch {
Write-Output "Error: $($_.Exception.Message)"
Write-Output "Note: REST API may need additional configuration"
}$idpConfig = @{
displayName = "Google OIDC"
protocol = "OIDC"
enabled = $true
config = @{
authorizationUrl = "https://accounts.google.com/o/oauth2/v2/auth"
tokenUrl = "https://oauth2.googleapis.com/token"
userinfoUrl = "https://openidconnect.googleapis.com/v1/userinfo"
clientId = "your-client-id"
clientSecret = "your-client-secret"
scope = "openid profile email"
}
mappers = @()
} | ConvertTo-Json
try {
$result = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/federation-hub/idps" -Headers $headers -Method Post -Body $idpConfig
Write-Output "IdP created successfully!"
$result | ConvertTo-Json
} catch {
Write-Output "Error: $($_.Exception.Message)"
}# List routing rules
$rules = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/federation-hub/routing-rules" -Headers $headers -Method Get
Write-Output "Found $($rules.Count) routing rules"-
Tạo 2 IdPs:
- IdP 1: Google (cho @gmail.com)
- IdP 2: Azure AD (cho @company.com)
-
Tạo routing rule:
{
"priority": 100,
"enabled": true,
"conditions": [
{
"field": "email_domain",
"operator": "equals",
"value": "gmail.com"
}
],
"targetIdpId": "google-oidc"
}- User với email
user@gmail.com→ Route to Google - User với email
user@company.com→ Route to Azure AD
- Tạo routing rule cho specific client:
{
"priority": 200,
"enabled": true,
"conditions": [
{
"field": "client_id",
"operator": "equals",
"value": "mobile-app"
}
],
"targetIdpId": "mobile-idp"
}- Login từ
mobile-appclient → Route to mobile-idp - Login từ client khác → Route theo default
- Tạo routing rule dựa trên header:
{
"priority": 150,
"enabled": true,
"conditions": [
{
"field": "header",
"key": "X-Partner",
"operator": "equals",
"value": "partner-a"
}
],
"targetIdpId": "partner-a-idp"
}- Request với header
X-Partner: partner-a→ Route to partner-a-idp - Request không có header → Route theo default
# Real-time logs
docker logs -f keycloak-federation-hub
# Filter federation logs
docker logs keycloak-federation-hub 2>&1 | grep -i federation
# Check for errors
docker logs keycloak-federation-hub 2>&1 | grep -i error
# Check specific provider
docker logs keycloak-federation-hub 2>&1 | grep -i "federation-hub-authenticator"# Connect to PostgreSQL
docker exec -it keycloak-postgres psql -U keycloak -d keycloak
# Check federation tables
\dt federation_*
# View IdP configs
SELECT id, display_name, protocol, enabled FROM federation_idp_config;
# View routing rules
SELECT id, priority, enabled, target_idp_id FROM federation_routing_rule;
# Exit
\q# Connect to Redis
docker exec -it keycloak-redis redis-cli
# List all keys
KEYS *
# Check federation cache keys
KEYS federation:*
KEYS idp:*
# Exit
exit# List topics
docker exec -it keycloak-kafka kafka-topics --list --bootstrap-server localhost:9092
# Consume federation events
docker exec -it keycloak-kafka kafka-console-consumer --bootstrap-server localhost:9092 --topic keycloak-federation-events --from-beginning- Mở http://localhost:9090
- Query các metrics:
keycloak_*- Keycloak metricsjvm_*- JVM metricshttp_*- HTTP metrics
- Mở http://localhost:3000
- Login: admin/admin
- Import dashboards:
- Keycloak Overview
- Federation Hub Metrics
- JVM Metrics
# Save as test-quick.ps1
Write-Host "Quick Federation Hub Test" -ForegroundColor Cyan
# 1. Health Check
$health = Invoke-WebRequest -Uri "http://localhost:8080/health/ready" -UseBasicParsing
Write-Host "Health: $($health.StatusCode)" -ForegroundColor Green
# 2. Count Providers
$providers = docker logs keycloak-federation-hub 2>&1 | Select-String "federation-"
Write-Host "Providers: $($providers.Count)" -ForegroundColor Green
# 3. Check Services
$services = docker-compose ps --format json 2>$null | ConvertFrom-Json
$running = ($services | Where-Object { $_.State -eq "running" }).Count
Write-Host "Services: $running/$($services.Count) running" -ForegroundColor Green
Write-Host "`nAll systems operational!" -ForegroundColor Green# Save as test-full.ps1
# Run: .\test-full.ps1
# Get token
$body = @{
username = "admin"
password = "admin"
grant_type = "password"
client_id = "admin-cli"
}
$tokenResponse = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/protocol/openid-connect/token" -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
$headers = @{
"Authorization" = "Bearer $($tokenResponse.access_token)"
"Content-Type" = "application/json"
}
# Test endpoints
Write-Host "Testing Federation Hub Endpoints..." -ForegroundColor Cyan
# 1. List IdPs
Write-Host "`n1. GET /federation-hub/idps"
try {
$idps = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/federation-hub/idps" -Headers $headers
Write-Host " Success: $($idps.Count) IdPs" -ForegroundColor Green
} catch {
Write-Host " Failed: $($_.Exception.Response.StatusCode)" -ForegroundColor Red
}
# 2. List Rules
Write-Host "`n2. GET /federation-hub/routing-rules"
try {
$rules = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/federation-hub/routing-rules" -Headers $headers
Write-Host " Success: $($rules.Count) rules" -ForegroundColor Green
} catch {
Write-Host " Failed: $($_.Exception.Response.StatusCode)" -ForegroundColor Red
}
# 3. Health Check
Write-Host "`n3. GET /federation-hub/health"
try {
$health = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/federation-hub/health" -Headers $headers
Write-Host " Success: Health check OK" -ForegroundColor Green
} catch {
Write-Host " Failed: $($_.Exception.Response.StatusCode)" -ForegroundColor Red
}Objective: Verify all providers load successfully
Steps:
- Start Keycloak:
docker-compose up -d - Wait for startup:
Start-Sleep -Seconds 30 - Check logs:
docker logs keycloak-federation-hub | grep federation
Expected Result:
- 4 providers loaded
- No errors in logs
- Providers visible in Server Info
Status: ✅ PASS
Objective: Verify authenticator is available in flows
Steps:
- Login to Admin Console
- Go to Authentication → Flows
- Create new flow
- Try to add execution
Expected Result:
federation-hub-authenticatorappears in execution list- Can be added to flow
- Can be configured
Status: ⏳ TO TEST
Objective: Verify mapper is available for clients
Steps:
- Go to Clients → Select client
- Go to Client Scopes → Mappers
- Click Add Mapper → By Configuration
Expected Result:
federation-partner-claims-mapperappears in list- Can be added to client scope
- Can be configured
Status: ⏳ TO TEST
Objective: Verify events are captured and logged
Steps:
- Enable federation-audit in Event Listeners
- Perform login/logout
- Check logs for events
Expected Result:
- Events captured
- Logged to console/Kafka
- Visible in Events tab
Status: ⏳ TO TEST
Objective: Verify REST API is accessible
Steps:
- Get admin token
- Call GET /federation-hub/idps
- Call GET /federation-hub/routing-rules
Expected Result:
- Endpoints return 200 OK
- Empty lists initially
- Can create/update/delete resources
Status:
Solution:
# Rebuild and restart
docker-compose build keycloak
docker-compose restart keycloak
# Check logs
docker logs keycloak-federation-hub | grep -i "provider"Solution:
- Clear browser cache
- Logout and login again
- Check Server Info → Providers
- Verify authenticator is loaded
Solution:
- Verify realm name is correct (master)
- Check token is valid
- Verify provider is loaded:
docker logs keycloak-federation-hub | grep "federation-hub"Solution:
- Verify event listener is enabled in Realm Settings
- Check event types are selected
- Verify "Save events" is enabled
- Check logs:
docker logs keycloak-federation-hub | grep "FederationEvent"# test-load.ps1
$iterations = 100
Write-Host "Running $iterations authentication tests..."
for ($i = 1; $i -le $iterations; $i++) {
$body = @{
username = "admin"
password = "admin"
grant_type = "password"
client_id = "admin-cli"
}
$start = Get-Date
$response = Invoke-RestMethod -Uri "http://localhost:8080/realms/master/protocol/openid-connect/token" -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
$duration = (Get-Date) - $start
if ($i % 10 -eq 0) {
Write-Host "Completed $i/$iterations (Avg: $($duration.TotalMilliseconds)ms)"
}
}
Write-Host "Load test complete!"# Watch metrics
watch -n 1 'docker stats keycloak-federation-hub --no-stream'
# Watch logs
docker logs -f keycloak-federation-hub | grep -i "federation"- All 4 providers load successfully
- No errors during startup
- Providers visible in Server Info
- Event listener initialized
- Authenticator works in flow
- Protocol mapper adds claims
- Events are captured
- REST API endpoints accessible
- IdP CRUD operations work
- Routing rules CRUD operations work
- Health checks return status
- Grafana dashboards configured
- Prometheus alerts setup
- Kafka events streaming
- Performance benchmarks
- See
deployment/examples/for sample IdP configs - See
deployment/examples/for sample routing rules
- Check logs:
docker logs keycloak-federation-hub - Check issues: GitHub Issues
- Documentation: README.md
Nếu bạn thấy:
- ✅ 4 providers trong Server Info
- ✅ Authenticator trong Authentication Flows
- ✅ Mapper trong Client Scopes
- ✅ Event Listener trong Events
- ✅ No errors in logs
Thì Federation Hub đã hoạt động thành công! 🚀