OAuth 2.0 ve OpenID Connect Rehberi

## OAuth 2.0 ve OpenID Connect: Kavramlar, Akışlar ve Güvenli Uygulama OAuth 2.0 bir yetkilendirme çerçevesidir; bir uygulamanın kullanıcı adına başk...

OAuth 2.0 ve OpenID Connect Rehberi

OAuth 2.0 ve OpenID Connect: Kavramlar, Akışlar ve Güvenli Uygulama

OAuth 2.0 bir yetkilendirme çerçevesidir; bir uygulamanın kullanıcı adına başka bir servisteki kaynaklara sınırlı erişim almasını sağlar. OpenID Connect (OIDC) ise OAuth 2.0 üzerine kurulu bir kimlik doğrulama katmanıdır ve "bu kullanıcı kim?" sorusunu standart bir şekilde yanıtlar. İkisini karıştırmak, sahada en sık yapılan mimari hatanın kaynağıdır: OAuth 2.0 tek başına kullanıcıyı tanımlamaz, yalnızca erişim yetkisi verir.

Bu rehberde terimleri netleştirip, akışları adım adım ele alacak, kod örneklerinde yalnızca doğruluğundan emin olduğum yapıları kullanacağım. Sürüme bağlı ayrıntılarda (örneğin kütüphane API'leri) güncel sürüm numarası uydurmak yerine, kavramsal ve protokol düzeyinde kalacağım.

Temel Terimler

  • Resource Owner: Kaynağın sahibi, genellikle son kullanıcı.
  • Client: Kaynağa erişmek isteyen uygulama (web, mobil, SPA, CLI).
  • Authorization Server: Kullanıcıyı doğrulayan ve token üreten sunucu.
  • Resource Server: Korumalı kaynakları barındıran API.
  • Access Token: Kaynağa erişim için kullanılan, süreli kimlik bilgisi.
  • Refresh Token: Access token süresi dolduğunda yenisini almak için kullanılır.
  • Scope: İstenen yetkinin kapsamı (örneğin read:profile).
  • ID Token (OIDC): Kullanıcı kimliğini taşıyan, imzalı JWT.

OAuth 2.0 Akışları

OAuth 2.0 birden fazla "grant type" tanımlar. Doğru akışı seçmek, güvenliğin ilk adımıdır.

Authorization Code + PKCE

Kullanıcı etkileşimi olan web, mobil ve SPA uygulamaları için önerilen akıştır. PKCE (Proof Key for Code Exchange), yetkilendirme kodunun ele geçirilmesi durumunda saldırganın token alamamasını sağlar.

Adımlar:

  1. Client, rastgele bir code_verifier üretir ve bundan code_challenge türetir (genellikle SHA-256 + Base64URL).
  2. Kullanıcı, authorization endpoint'ine yönlendirilir; code_challenge ve code_challenge_method=S256 gönderilir.
  3. Kullanıcı giriş yapıp onay verir; authorization server bir code ile geri yönlendirir.
  4. Client, code ile birlikte code_verifier'ı token endpoint'ine gönderir.
  5. Server, code_challenge ile code_verifier'ı doğrular ve token'ları döner.

PKCE'nin plain yerine S256 yöntemiyle kullanılması tercih edilmelidir.

Client Credentials

Kullanıcı yoktur; servisler arası (machine-to-machine) erişim içindir. Client, kendi kimlik bilgileriyle doğrudan token alır.

Device Code

Tarayıcısı veya klavyesi kısıtlı cihazlar (TV, CLI) içindir. Cihaz bir kod gösterir, kullanıcı başka bir cihazdan bu kodu onaylar.

Kullanımdan Kaçınılması Gerekenler

  • Implicit Flow: Token'lar URL fragment'ında taşınır; SPA'lar için artık Authorization Code + PKCE tercih edilmelidir.
  • Resource Owner Password Credentials: Kullanıcı parolasının client'a verilmesini gerektirir; güven modelini bozar.

OpenID Connect Katmanı

OIDC, OAuth 2.0'a şu eklemeleri yapar:

  • ID Token: İmzalı JWT; iss, sub, aud, exp, iat gibi standart claim'ler taşır.
  • UserInfo Endpoint: Access token ile çağrılan, kullanıcı bilgisi dönen endpoint.
  • Discovery: /.well-known/openid-configuration üzerinden endpoint'ler ve anahtarlar keşfedilir.
  • JWKS: ID token imzasını doğrulamak için kullanılan açık anahtarlar.

Kimlik doğrulama gerekiyorsa scope içine mutlaka openid eklenir. openid olmadan dönen yanıt bir OIDC yanıtı değildir.

Token Doğrulama: Neye Dikkat Edilmeli

ID token bir JWT ise, doğrulama sırasında şu kontroller atlanmamalıdır:

  • İmza, sağlayıcının JWKS'inden alınan anahtarla doğrulanmalı.
  • iss beklenen sağlayıcıyla eşleşmeli.
  • aud kendi client ID'nizle eşleşmeli.
  • exp ve iat zaman penceresi kontrol edilmeli.
  • Algoritma, token başlığındaki alg'a körü körüne güvenilmeden sabitlenmeli.

alg: none kabul eden bir doğrulayıcı, imza kontrolünü tamamen devre dışı bırakır. Kütüphanelerin varsayılanlarına güvenmek yerine, izin verilen algoritmalar açıkça belirtilmelidir.

Kod Örneği: Authorization Code + PKCE (Node.js)

Aşağıdaki örnek, PKCE için code_verifier ve code_challenge üretimini ve token değişimini gösterir. Node.js'in yerleşik crypto ve fetch API'lerini kullanır.

const crypto = require('crypto');

function base64url(buffer) {
  return buffer
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

function createPkcePair() {
  const verifier = base64url(crypto.randomBytes(32));
  const challenge = base64url(
    crypto.createHash('sha256').update(verifier).digest()
  );
  return { verifier, challenge };
}

async function exchangeCodeForTokens({ tokenEndpoint, code, verifier, clientId, redirectUri }) {
  const body = new URLSearchParams({
    grant_type: 'authorization_code',
    code,
    code_verifier: verifier,
    client_id: clientId,
    redirect_uri: redirectUri,
  });

  const res = await fetch(tokenEndpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body,
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`Token endpoint hatası: ${res.status} ${text}`);
  }
  return res.json();
}

Beklenen davranış: exchangeCodeForTokens, geçerli bir kod ve eşleşen code_verifier ile çağrıldığında access_token, genellikle refresh_token ve (OIDC ise) id_token içeren bir JSON döner. Kod veya verifier uyuşmazsa token endpoint'i hata döner.

Bu örnek, protokol düzeyindeki adımları göstermek için yazılmıştır; üretimde kütüphane kullanmak daha güvenlidir çünkü state yönetimi, nonce ve hata durumları elle yönetilmesi kolay olmayan ayrıntılardır.

Güvenlik Kontrol Listesi

  • PKCE kullanın: Authorization Code akışında S256 zorunlu kabul edilmeli.
  • state parametresi: CSRF'e karşı, istemcide saklanan rastgele bir değerle karşılaştırılmalı.
  • nonce (OIDC): ID token'ın tekrar oynatılmasını engellemek için kullanılmalı.
  • Redirect URI: Tam eşleşme ile doğrulanmalı; joker karakterlerden kaçınılmalı.
  • Token saklama: Tarayıcıda localStorage yerine, mümkünse HttpOnly + Secure çerezler veya bellek içi saklama tercih edilmeli.
  • Scope minimizasyonu: Yalnızca gereken scope'lar istenmeli.
  • Token ömrü: Access token kısa, refresh token rotasyonlu tutulmalı.
  • HTTPS: Tüm uç noktalar TLS üzerinden çalışmalı.

Yaygın Hatalar

  • OAuth'u kimlik doğrulama sanmak: Access token "kim" sorusunu yanıtlamaz; kimlik için OIDC'nin ID token'ı gerekir.
  • Implicit flow'u SPA'da kullanmak: Token'lar URL'de görünür; PKCE'li Authorization Code tercih edilmelidir.
  • ID token'ı doğrulamadan kullanmak: İmza ve claim kontrolleri atlanırsa sahte token kabul edilebilir.
  • state ve nonce üretmemek: CSRF ve replay saldırılarına açık hale gelir.
  • Refresh token'ı istemciye açık şekilde bırakmak: Çalınması durumunda uzun süreli erişim sağlar; rotasyon uygulanmalıdır.
  • Kapsamı çok geniş tutmak: Gereksiz yetkiler, ihlal durumunda etki alanını büyütür.

Sonuç

OAuth 2.0 yetki, OIDC kimlik içindir. Kullanıcı etkileşimi olan uygulamalarda PKCE'li Authorization Code akışı, servisler arası erişimde Client Credentials, kısıtlı cihazlarda Device Code tercih edilmelidir. Token doğrulamasında imza, iss, aud, exp ve algoritma sabitlemesi pazarlık konusu değildir. state, nonce, dar scope ve kısa ömürlü token'lar, çerçevenin sağladığı güvenliğin uygulamada da korunmasını sağlar. Kütüphane seçerken protokol ayrıntılarını doğru uyguladığını belgeleyen, aktif bakımda olan seçenekler değerlendirilmelidir.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz