Skip to main content
Her ortamın (dev / stage / prod) kendi Keycloak instance’ı ve kendi realm çiftleri vardır. Realm isimleri ortam suffix’i ile tekrarlanır.
OrtamVatandaş RealmPersonel RealmKeycloak
devdiyanet-vatandas-dev-realmdiyanet-yonetim-dev-realmcontainer (localhost:8080), otomatik provisioning
stagediyanet-vatandas-stage-realmdiyanet-yonetim-stage-realmharici / paylaşımlı
proddiyanet-vatandas-prod-realmdiyanet-yonetim-prod-realmharici (müşteri)

Dev

  • Keycloak bir Docker container’ıdır (docker-compose.override.yml, keycloak26).
  • API açılışta KeycloakProvisioning ile realm/client/rol/kullanıcı/mapper’ı otomatik kurar (Enabled: true, RunOnce: true).
  • RequireHttpsMetadata: false — HTTP yeterlidir.
  • Tarayıcı ve API aynı localhost:8080’i gördüğü için BaseUrl == PublicBaseUrl.

Stage / Prod

  • Keycloak genelde müşterinin harici instance’ıdır (https://auth.diyanet.gov.tr).
  • Provisioning kapatılır (Enabled: false); realm bir kez kurulup yönetilir.
  • RequireHttpsMetadata: true olmalı.
  • Realm/URL değerleri .env üzerinden gelir.
# .env.stage / .env.prod (kritik Keycloak değişkenleri)
KEYCLOAK_BASE_URL=https://auth.diyanet.gov.tr       # API → Keycloak (internal/external)
KEYCLOAK_EXTERNAL_URL=https://auth.diyanet.gov.tr   # tarayıcının gördüğü URL

BaseUrl vs PublicBaseUrl

Bu ayrım çift-realm doğrulamanın kalbidir (KeycloakSchemeOptions):
AlanAnlam
BaseUrlAPI’nin Keycloak’a ulaştığı URL. Docker dev’de iç ağ hostname’i olabilir (http://diyanet-keycloak:8080). JWKS metadata fetch ve Authority buradan hesaplanır.
PublicBaseUrlTarayıcının gördüğü URL. Token’ın iss claim’i bunu taşır. Boşsa BaseUrl ile aynı kabul edilir.
Authority     = {BaseUrl}/realms/{Realm}            → JWKS / metadata (API tarafı)
Issuer        = Authority
PublicIssuer  = {PublicBaseUrl}/realms/{Realm}      → token "iss" (browser tarafı)
Issuer doğrulaması her ikisini de kabul eder:
var validIssuers = scheme.Issuer == scheme.PublicIssuer
    ? new[] { scheme.Issuer }
    : new[] { scheme.Issuer, scheme.PublicIssuer };
Docker dev’de API container’ı Keycloak’a diyanet-keycloak:8080 üzerinden ulaşır ama token’ın iss’i localhost:8080’dir. PublicBaseUrl set edilmezse issuer mismatch → her token 401 alır. Bu yüzden BaseUrl ile PublicBaseUrl farklıysa ikisini de doğru girin.

Hetzner paylaşımlı Keycloak

Hetzner çoklu-proje kurulumunda (docker-compose.platform.yml / .shared-infra.yml) Keycloak platform seviyesinde paylaşımlıdır: birden fazla proje aynı Keycloak instance’ını kullanır, her proje kendi realm çiftiyle izole olur. Bu durumda:
  • KEYCLOAK_BASE_URL paylaşımlı Keycloak’ı işaret eder.
  • Realm isimleri proje + ortam ile ayrışır (ProjectKeycloakId template sembolü).
  • Provisioning genelde kapalıdır; realm’ler bir kez platform kurulumunda hazırlanır.

Ortam doğrulama

API açılışında console’a hangi URL’lerin kullanıldığı yazılır (BuildingBlocks.Keycloak/DependencyInjection.cs):
[Keycloak JWT] Vatandas Authority    = http://localhost:8080/realms/diyanet-vatandas-dev-realm
[Keycloak JWT] Vatandas PublicIssuer = http://localhost:8080/realms/diyanet-vatandas-dev-realm
[Keycloak JWT] Personel Authority    = http://localhost:8080/realms/diyanet-yonetim-dev-realm
[Keycloak JWT] Vatandas metadata REACHABLE ✓ (.../.well-known/openid-configuration)
UNREACHABLE görürseniz BaseUrl API’den erişilebilir değildir (bkz. Sorun Giderme).

İlgili

Provisioning

Hangi ortamda otomatik kurulum açık.

Sorun Giderme

Issuer mismatch ve metadata erişim hataları.

Authentication

Issuer / audience doğrulama detayları.

Realm Yapısı

Realm ve rol yapısı.