SSO Mimarisi ve Entegrasyon Rehberi

# SSO Mimarisi ve Entegrasyonu: Uygulanabilir Bir Geliştirici Rehberi SSO (Single Sign-On), kullanıcının bir kimlik sağlayıcıda (IdP) bir kez kimlik...

SSO Mimarisi ve Entegrasyon Rehberi

SSO Mimarisi ve Entegrasyonu: Uygulanabilir Bir Geliştirici Rehberi

SSO (Single Sign-On), kullanıcının bir kimlik sağlayıcıda (IdP) bir kez kimlik doğrulaması yapıp, güvendiği birden çok uygulamaya (SP — Service Provider) ayrı ayrı şifre girmeden erişebilmesini sağlar. Bu rehber, SSO'nun arkasındaki mimariyi ve bir uygulamaya nasıl entegre edileceğini adım adım anlatır. OAuth 2.0 ve OpenID Connect (OIDC) protokol ayrıntılarına ayrı bir yazıda değinildiği için burada yalnızca SSO bağlamında gerekli olan kadarına yer verilecek.

Önkoşullar ve Kapsam

  • HTTP, çerez (cookie), oturum (session) ve temel kriptografi (imza, özet) kavramlarına aşinalık.
  • Sunucu tarafı bir web çatısı (örneklerde dil bağımsız akış ve Python/Flask benzeri sözde kod).
  • Bir IdP hesabı: Keycloak, Okta, Auth0, Entra ID veya Google Workspace gibi. Rehber belirli bir sağlayıcının sürümüne bağlı değildir; protokol düzeyinde kalır.
  • HTTPS zorunludur. SSO'yu düz HTTP üzerinde çalıştırmayın.

Sürüm notu: OIDC, OAuth 2.0 üzerine kuruludur. OAuth 2.1 henüz taslak aşamasındadır; bu rehber OAuth 2.0 ve OIDC'nin yaygın olarak uygulanan davranışlarını esas alır. Belirli bir kütüphane sürümü iddia edilmiyor; kullandığınız kütüphanenin güncel belgelerini kontrol edin.

Temel Roller ve Kavramlar

  • IdP (Identity Provider): Kimliği doğrular, token üretir. Örn. Keycloak, Entra ID.
  • SP / RP (Service Provider / Relying Party): Kullanıcıyı IdP'ye yönlendiren ve dönen token'ı doğrulayan uygulama. Sizin uygulamanız.
  • Realm / Tenant: Kullanıcı ve istemci (client) gruplarını izole eden kapsam.
  • Client ID / Client Secret: Uygulamanızın IdP'deki kimliği. Gizli istemcilerde (sunucu tarafı) secret gizli tutulur; SPA ve mobil gibi genel istemcilerde (public client) secret kullanılmaz, PKCE uygulanır.

SSO Akışı: Adım Adım

Aşağıdaki akış Authorization Code + PKCE akışıdır; SSO entegrasyonunda en yaygın ve önerilen yaklaşımdır.

1. IdP'de istemci kaydı

IdP panelinde yeni bir istemci oluşturun ve şu alanları ayarlayın:

  • Redirect URI (Callback URL): Örn. https://app.example.com/auth/callback. Bu adres IdP'de birebir kayıtlı olmalı; aksi halde IdP isteği reddeder.
  • Post-logout redirect URI: Çıkış sonrası dönülecek adres.
  • Grant type: Authorization Code.
  • Scopes: En az openid; profil için profile, e-posta için email.

2. Kullanıcıyı IdP'ye yönlendirme

Uygulama, korumalı bir kaynağa erişim isteyen oturumsuz kullanıcıyı IdP'nin yetkilendirme uç noktasına yönlendirir.

GET https://idp.example.com/authorize
  ?response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https://app.example.com/auth/callback
  &scope=openid%20profile%20email
  &state=RASTGELE_DEGER
  &code_challenge=PKCE_CHALLENGE
  &code_challenge_method=S256
  • state: CSRF koruması için rastgele üretilir ve oturumda saklanır; callback'te birebir karşılaştırılır.
  • code_challenge: PKCE için üretilen code_verifier'ın SHA-256 özetinin base64url kodlaması.

PKCE üretimi (dil bağımsız mantık):

import os, hashlib, base64

code_verifier = base64.urlsafe_b64encode(os.urandom(32)).rstrip(b"=").decode()
digest = hashlib.sha256(code_verifier.encode()).digest()
code_challenge = base64.urlsafe_b64encode(digest).rstrip(b"=").decode()

code_verifier sunucu tarafında oturuma bağlı olarak saklanır; callback'te token isteğinde kullanılır.

3. Callback ve kod değişimi

Kullanıcı IdP'de kimlik doğruladıktan sonra redirect_uri'ye code ve state parametreleriyle döner. Uygulama:

  1. state değerini oturumdakiyle karşılaştırır; uyuşmazsa isteği reddeder.
  2. Kodu token uç noktasında token'a çevirir.
POST https://idp.example.com/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=DONEN_KOD
&redirect_uri=https://app.example.com/auth/callback
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&code_verifier=SAKLANAN_VERIFIER

Yanıt tipik olarak şunları içerir:

{
  "access_token": "...",
  "id_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600
}

4. ID token doğrulama

id_token, kullanıcının kimliğini taşıyan bir JWT'dir. Kullanmadan önce mutlaka doğrulayın:

  • İmza: IdP'nin JWKS uç noktasından (/.well-known/jwks.json) açık anahtarları çekip imzayı doğrulayın.
  • iss: Beklenen issuer ile eşleşmeli.
  • aud: Kendi client_id'nizle eşleşmeli.
  • exp / iat: Süre kontrolü yapılmalı.
  • nonce: Yönlendirme sırasında gönderdiyseniz eşleşmeli.

Doğrulama olmadan id_token içeriğine güvenmek, saldırganın sahte token üretmesine kapı açar.

5. Yerel oturum oluşturma

Token'ları tarayıcıya açık şekilde bırakmak yerine, sunucu tarafında kendi oturum çerezini oluşturun. Çerez ayarları:

  • HttpOnly, Secure, SameSite=Lax (veya uygulama akışına göre Strict).
  • Oturum kimliği tahmin edilemez ve sunucuda saklanır.

Böylece SSO, "kimlik doğrulama katmanı" olarak kalır; yetkilendirme ve oturum yönetimi uygulamanın kendi sorumluluğundadır.

Çoklu Uygulama (Gerçek SSO) Davranışı

Tek uygulama için yukarıdaki akış yeterlidir. SSO'nun asıl faydası, aynı IdP'ye bağlı birden çok uygulamada görülür:

  • Kullanıcı A uygulamasında oturum açtığında IdP tarayıcıda kendi oturum çerezini tutar.
  • B uygulamasına gittiğinde yönlendirme IdP'ye gider, IdP mevcut oturumu görür ve kullanıcıdan tekrar şifre istemeden kod döner.

Bu davranışın çalışması için tüm uygulamaların aynı IdP realm'ine/tenant'ına bağlı olması ve tarayıcının IdP çerezlerini engellememesi gerekir.

Yaygın Hatalar

  • state kontrolünü atlamak: CSRF'e açık hale gelir. Her istekte üretip callback'te doğrulayın.
  • PKCE'yi yalnızca SPA'larda sanmak: Genel istemcilerde zorunlu, gizli istemcilerde de önerilir.
  • ID token'ı doğrulamadan kullanmak: Sahte token riski. İmza, iss, aud, exp kontrolü şart.
  • Redirect URI'de joker karakter kullanmak: IdP'de tam eşleşme tercih edin; gevşek eşleşme açık yönlendirme (open redirect) riskini büyütür.
  • Token'ları localStorage'da saklamak: XSS durumunda çalınır. Sunucu tarafı oturum çerezini tercih edin.
  • Client secret'ı istemci koduna gömmek: SPA ve mobilde secret bulunmamalı; yalnızca PKCE kullanılmalı.
  • Oturum kapatmayı yalnızca yerel yapmak: IdP oturumu açık kalırsa, kullanıcı çıkış yaptıktan sonra başka bir uygulamaya tekrar otomatik girebilir. RP-initiated logout akışını uygulayın.
  • Saat kayması: Token doğrulaması exp/iat karşılaştırmasına dayanır; sunucu saatleri senkron olmalı (NTP).

Güvenlik Etkileri

  • Token ömrü: Access token'ları kısa tutun; yenileme (refresh) için ayrı ve korumalı bir akış kullanın.
  • Scope minimizasyonu: Yalnızca ihtiyaç duyulan scope'ları isteyin.
  • JWKS önbelleği: Anahtarları önbelleğe alın ama kid değişimlerini ve anahtar rotasyonunu destekleyin.
  • Loglama: Token ve authorization code değerlerini loglara yazmayın.
  • Çıkış: Hem yerel oturumu hem IdP oturumunu sonlandırın; aksi halde paylaşılan cihazlarda hesap açık kalır.
  • Çok kiracılı (multi-tenant) senaryolar: Her tenant için iss ve aud beklentisini ayrı doğrulayın; karışık doğrulama, tenant sınırlarının aşılmasına yol açar.

Sonuç

SSO entegrasyonu, protokol düzeyinde bakıldığında birkaç adımdan oluşur: istemci kaydı, yönlendirme, kod değişimi, token doğrulama ve yerel oturum. Kritik nokta, token'ları doğrulamadan kullanmamak ve oturum güvenliğini uygulamanın kendi tarafında sağlamaktır. IdP'ye bağlı birden çok uygulamanız varsa, aynı realm/tenant yapılandırması ve tutarlı çıkış akışı, gerçek SSO deneyimini belirleyen unsurlardır.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz