This repository has been archived on 2026-01-03. You can view files and clone it, but cannot push or open issues or pull requests.
Files
lions-user-manager/scripts/setup-keycloak-production.ps1

319 lines
13 KiB
PowerShell
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env pwsh
<#
.SYNOPSIS
Script pour configurer Keycloak en production pour Lions User Manager
.DESCRIPTION
Ce script configure Keycloak production avec :
- Création des clients OIDC (frontend + backend)
- Création des rôles realm
- Configuration des protocol mappers
- Assignation des rôles au service account
.PARAMETER KeycloakUrl
URL de Keycloak (défaut: https://security.lions.dev)
.PARAMETER Realm
Realm Keycloak (défaut: master)
.PARAMETER AdminUsername
Nom d'utilisateur admin Keycloak
.PARAMETER AdminPassword
Mot de passe admin Keycloak
.EXAMPLE
.\setup-keycloak-production.ps1 -AdminUsername admin -AdminPassword "your-password"
#>
param(
[Parameter(Mandatory=$false)]
[string]$KeycloakUrl = "https://security.lions.dev",
[Parameter(Mandatory=$false)]
[string]$Realm = "master",
[Parameter(Mandatory=$true)]
[string]$AdminUsername,
[Parameter(Mandatory=$true)]
[string]$AdminPassword
)
$ErrorActionPreference = "Stop"
# Couleurs
function Write-Success { Write-Host "$args" -ForegroundColor Green }
function Write-Info { Write-Host " $args" -ForegroundColor Cyan }
function Write-Warning { Write-Host "⚠️ $args" -ForegroundColor Yellow }
function Write-Error { Write-Host "$args" -ForegroundColor Red }
function Write-Step { Write-Host "`n🚀 $args" -ForegroundColor Magenta }
Write-Host @"
🔐 CONFIGURATION KEYCLOAK PRODUCTION - LIONS USER MANAGER 🔐
"@ -ForegroundColor Cyan
Write-Info "Keycloak URL: $KeycloakUrl"
Write-Info "Realm: $Realm"
Write-Info "Admin Username: $AdminUsername"
Write-Info ""
# 1. Obtenir le token admin
Write-Step "1. Obtention du token admin Keycloak..."
$tokenUrl = "$KeycloakUrl/realms/$Realm/protocol/openid-connect/token"
$tokenBody = @{
username = $AdminUsername
password = $AdminPassword
grant_type = "password"
client_id = "admin-cli"
} | ConvertTo-Json
try {
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $tokenBody -ContentType "application/json"
$accessToken = $tokenResponse.access_token
if ([string]::IsNullOrEmpty($accessToken)) {
Write-Error "Impossible d'obtenir le token admin"
exit 1
}
Write-Success "Token admin obtenu"
} catch {
Write-Error "Erreur lors de l'obtention du token: $($_.Exception.Message)"
exit 1
}
$headers = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = "application/json"
}
# 2. Créer les rôles realm
Write-Step "2. Création des rôles realm..."
$roles = @(
@{name="admin"; description="System administrator with full access"},
@{name="user_manager"; description="User manager - Can create, update, delete users"},
@{name="user_viewer"; description="User viewer - Read-only access to users"},
@{name="auditor"; description="Auditor - Can view audit logs"},
@{name="sync_manager"; description="Sync manager - Can manage synchronization"},
@{name="role_manager"; description="Role manager - Can create, update, delete roles"},
@{name="role_viewer"; description="Role viewer - Read-only access to roles"}
)
foreach ($role in $roles) {
$roleUrl = "$KeycloakUrl/admin/realms/$Realm/roles"
$roleBody = @{
name = $role.name
description = $role.description
composite = $false
clientRole = $false
} | ConvertTo-Json -Compress
try {
$existingRole = Invoke-RestMethod -Uri "$roleUrl/$($role.name)" -Method Get -Headers $headers -ErrorAction SilentlyContinue
Write-Warning "Rôle $($role.name) existe déjà, ignoré"
} catch {
try {
Invoke-RestMethod -Uri $roleUrl -Method Post -Headers $headers -Body $roleBody | Out-Null
Write-Success "Rôle $($role.name) créé"
} catch {
Write-Warning "Erreur création rôle $($role.name): $($_.Exception.Message)"
}
}
}
# 3. Créer le client frontend
Write-Step "3. Création du client frontend (lions-user-manager-client)..."
$frontendClientUrl = "$KeycloakUrl/admin/realms/$Realm/clients"
$frontendClientBody = @{
clientId = "lions-user-manager-client"
name = "Lions User Manager Client (Frontend)"
description = "Frontend application for Lions User Manager"
enabled = $true
publicClient = $true
standardFlowEnabled = $true
directAccessGrantsEnabled = $false
serviceAccountsEnabled = $false
redirectUris = @(
"https://user-manager.lions.dev/*",
"https://admin.lions.dev/*",
"https://user-manager.lions.dev/auth/callback"
)
webOrigins = @(
"https://user-manager.lions.dev",
"https://admin.lions.dev"
)
protocol = "openid-connect"
attributes = @{
"pkce.code.challenge.method" = "S256"
"use.refresh.tokens" = "true"
"frontchannel.logout.session.required" = "true"
}
} | ConvertTo-Json -Depth 10 -Compress
try {
# Vérifier si le client existe
$clients = Invoke-RestMethod -Uri $frontendClientUrl -Method Get -Headers $headers
$existingClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager-client" }
if ($existingClient) {
Write-Warning "Client frontend existe déjà (ID: $($existingClient.id))"
$frontendClientId = $existingClient.id
} else {
$response = Invoke-RestMethod -Uri $frontendClientUrl -Method Post -Headers $headers -Body $frontendClientBody
Write-Success "Client frontend créé"
# Récupérer l'ID du client créé
$clients = Invoke-RestMethod -Uri $frontendClientUrl -Method Get -Headers $headers
$frontendClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager-client" }
$frontendClientId = $frontendClient.id
}
} catch {
Write-Error "Erreur création client frontend: $($_.Exception.Message)"
exit 1
}
# 4. Créer le client backend (service account)
Write-Step "4. Création du client backend (lions-user-manager) avec service account..."
$backendClientUrl = "$KeycloakUrl/admin/realms/$Realm/clients"
$backendClientBody = @{
clientId = "lions-user-manager"
name = "Lions User Manager Server (Backend)"
description = "Backend API for Lions User Manager with service account"
enabled = $true
publicClient = $false
standardFlowEnabled = $false
directAccessGrantsEnabled = $true
serviceAccountsEnabled = $true
authorizationServicesEnabled = $true
protocol = "openid-connect"
attributes = @{
"access.token.lifespan" = "300"
"client.session.idle.timeout" = "1800"
"client.session.max.lifespan" = "36000"
}
} | ConvertTo-Json -Depth 10 -Compress
try {
# Vérifier si le client existe
$clients = Invoke-RestMethod -Uri $backendClientUrl -Method Get -Headers $headers
$existingClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager" }
if ($existingClient) {
Write-Warning "Client backend existe déjà (ID: $($existingClient.id))"
$backendClientId = $existingClient.id
} else {
$response = Invoke-RestMethod -Uri $backendClientUrl -Method Post -Headers $headers -Body $backendClientBody
Write-Success "Client backend créé"
# Récupérer l'ID du client créé
$clients = Invoke-RestMethod -Uri $backendClientUrl -Method Get -Headers $headers
$backendClient = $clients | Where-Object { $_.clientId -eq "lions-user-manager" }
$backendClientId = $backendClient.id
}
# Récupérer le secret du client backend
$secretUrl = "$KeycloakUrl/admin/realms/$Realm/clients/$backendClientId/client-secret"
$secretResponse = Invoke-RestMethod -Uri $secretUrl -Method Get -Headers $headers
$backendSecret = $secretResponse.value
Write-Success "Secret backend récupéré: $backendSecret"
Write-Info "⚠️ IMPORTANT: Sauvegardez ce secret pour la configuration Kubernetes !"
} catch {
Write-Error "Erreur création client backend: $($_.Exception.Message)"
exit 1
}
# 5. Assigner les rôles au service account
Write-Step "5. Assignation des rôles au service account backend..."
try {
# Récupérer l'ID du service account
$serviceAccountUrl = "$KeycloakUrl/admin/realms/$Realm/clients/$backendClientId/service-account-user"
$serviceAccount = Invoke-RestMethod -Uri $serviceAccountUrl -Method Get -Headers $headers
$serviceAccountId = $serviceAccount.id
# Récupérer les rôles à assigner
$rolesToAssign = @("admin", "user_manager", "auditor", "sync_manager", "role_manager")
$realmRoles = Invoke-RestMethod -Uri "$KeycloakUrl/admin/realms/$Realm/roles" -Method Get -Headers $headers
$rolesToAssignObjects = $realmRoles | Where-Object { $rolesToAssign -contains $_.name }
# Assigner les rôles
$assignRolesUrl = "$KeycloakUrl/admin/realms/$Realm/users/$serviceAccountId/role-mappings/realm"
$rolesBody = $rolesToAssignObjects | ConvertTo-Json -Depth 10
Invoke-RestMethod -Uri $assignRolesUrl -Method Post -Headers $headers -Body $rolesBody | Out-Null
Write-Success "Rôles assignés au service account: $($rolesToAssign -join ', ')"
} catch {
Write-Warning "Erreur assignation rôles au service account: $($_.Exception.Message)"
Write-Info "Vous devrez assigner les rôles manuellement dans Keycloak Admin Console"
}
# 6. Vérifier le protocol mapper roles
Write-Step "6. Vérification du protocol mapper 'roles'..."
try {
$clientScopesUrl = "$KeycloakUrl/admin/realms/$Realm/client-scopes"
$clientScopes = Invoke-RestMethod -Uri $clientScopesUrl -Method Get -Headers $headers
$rolesScope = $clientScopes | Where-Object { $_.name -eq "roles" }
if ($rolesScope) {
$mappersUrl = "$KeycloakUrl/admin/realms/$Realm/client-scopes/$($rolesScope.id)/protocol-mappers/models"
$mappers = Invoke-RestMethod -Uri $mappersUrl -Method Get -Headers $headers
$realmRolesMapper = $mappers | Where-Object { $_.name -eq "realm roles" }
if ($realmRolesMapper) {
Write-Success "Protocol mapper 'realm roles' trouvé"
Write-Info "Vérifiez qu'il est configuré pour l'access token (claim: realm_access.roles)"
} else {
Write-Warning "Protocol mapper 'realm roles' non trouvé - à créer manuellement"
}
} else {
Write-Warning "Client scope 'roles' non trouvé - à créer manuellement"
}
} catch {
Write-Warning "Erreur vérification protocol mapper: $($_.Exception.Message)"
}
# 7. Résumé
Write-Step "7. Résumé de la configuration..."
Write-Host @"
CONFIGURATION KEYCLOAK TERMINÉE
"@ -ForegroundColor Green
Write-Host "📋 INFORMATIONS IMPORTANTES:" -ForegroundColor Yellow
Write-Host ""
Write-Host "🔑 SECRET BACKEND (Service Account):" -ForegroundColor Cyan
Write-Host " $backendSecret" -ForegroundColor White
Write-Host ""
Write-Host "⚠️ ACTIONS REQUISES:" -ForegroundColor Yellow
Write-Host " 1. Sauvegardez le secret backend ci-dessus"
Write-Host " 2. Vérifiez le protocol mapper 'roles' dans Keycloak Admin Console"
Write-Host " 3. Vérifiez que les rôles sont assignés au service account"
Write-Host " 4. Créez les secrets Kubernetes avec ces informations"
Write-Host ""
Write-Host "🔗 URLS:" -ForegroundColor Cyan
Write-Host " Keycloak Admin: $KeycloakUrl/admin"
Write-Host " Realm: $Realm"
Write-Host ""