403 not_invited alır.
İlgili dosyalar:
src/DiyanetCleanArchitecture.API/Controllers/AuthController.cs (Keycloak akışları) ·
Application/Features/Authentication/Admin/Commands/ProvisionKeycloakUser/* ·
API/SeedWork/Authorization/ActiveAccountAuthorizationHandler.cs ·
Application/Features/Users/Admin/Queries/GetAdminMe/*Realm ve client
| Realm (dev) | Client | Token süresi | |
|---|---|---|---|
| Personel (yönetim) | diyanet-yonetim-dev-realm | diyanet-admin | 5 dk |
| Vatandaş (website) | diyanet-vatandas-dev-realm | diyanet-website | 2 saat |
keycloak-js ile Authorization Code + PKCE (S256) akışını kullanır. 5 dakikalık kısa access token, keycloak-js’in sessiz (silent) refresh mekanizmasıyla yenilenir.
Sequence — ilk personel girişi
Adım adım
SPA → Keycloak (PKCE)
Admin SPA
keycloak-js ile Authorization Code + PKCE akışını başlatır. Kullanıcı Keycloak login formunda kimlik doğrular; SPA access_token (5 dk) ve refresh_token alır. API bu adımda devrede değildir.Session — token doğrulama + cookie
SPA token’ı
keycloak/session endpoint’ine gönderir. API token’ı JWKS ile offline doğrular (Keycloak’a gidilmez) ve HTTP-only cookie set eder:Raw token cookie’ye gömülür; React bir daha token’ı header’a koymaz, tüm istekler
kc_token cookie’siyle gider (BFF deseni). SecureCookie dev’de false, prod’da true’dur.Provisioning — davet bazlı eşleme
Doğrulanan payload
ProvisionKeycloakUserCommand’a dönüştürülür. Handler yalnızca Personel realm için çalışır (ResolveRealmKind(iss)); başka realm gelirse unknown_realm ile reddeder. Sonra üç olasılık denenir, hepsi tek transaction içinde:User.ActivateOnExternalLogin() idempotenttir: Draft/Pending ise Active’e geçirip true döner, zaten Active ise false. Banned/Suspended kullanıcılara dokunmaz; login zaten reddedilir.403 senaryoları — cookie temizliği
Provisioning bir Frontend bu
ExternalLoginNotAllowedException (not_invited / account_blocked / unknown_realm) ya da beklenmeyen hata fırlatırsa controller cookie’leri temizler ve 403 döner — daveti olmayan kullanıcının dashboard’a düşmesi engellenir:reason koduna göre AccessDeniedScreen gösterir.Yetkili istekler — JwtBearer Personel şeması
Bundan sonraki tüm istekler
kc_token cookie’siyle gelir. API’de JwtBearer “Personel” şeması token’ı doğrular ve claim’leri okur: permissions (multivalued), organization_id / tenant_id, accountStatus. Otorizasyon kararı her zaman lokal DB’deki rol + tenant’a dayanır; Keycloak’ın ClientRoles’u yetkiye dönüşmez (yalnızca audit/debug için loglanır).Authorization — aktif hesap + permission policy
İki kademe çalışır. Önce
ActiveAccountAuthorizationHandler hesabın accountStatus’unun aktif olduğunu kontrol eder; sonra endpoint’in [Authorize(Policy = "...")] permission policy’si permissions claim’iyle eşleştirilir. Pipeline’da Application tarafında ayrıca PermissionPipelineBehavior çalışır. Bkz. Authorization.Token yenileme ve çıkış
- Refresh: 5 dakikalık kısa token nedeniyle
keycloak/refreshsık çağrılır. API refresh token’la Keycloak’tan yeni token alır, cookie’leri günceller veIUserContextProvider.InvalidateAsync(sub)ile permission cache’ini düşürür (yetkiler değişmiş olabilir). - Logout:
POST /api/auth/logoutcookie’leri siler. Keycloak oturumunu da bitirmek için frontend ayrıca Keycloakend_sessionURL’ini açmalıdır.
Hata senaryoları
| Durum | reason | HTTP |
|---|---|---|
| Davet yok (eşleşme bulunamadı) | not_invited | 403 |
| Banned / Suspended hesap | account_blocked | 403 |
| Bilinmeyen / yanlış realm | unknown_realm | 403 |
| Provision sırasında beklenmeyen hata | provision_error | 403 (güvenli varsayılan: erişim reddedilir) |
| Geçersiz Keycloak token | — | 401 |
İlgili
Keycloak Provisioning
Realm/client/user otomatik kurulumu (RunOnce).
Authorization
Permission policy ve aktif hesap kontrolü.
Keycloak Ortamları
Dev/stage/prod realm farkları.
OTP / TOTP Akışı
Vatandaş tarafı yerel kimlik akışı.