ERETEK
BİLGİ SİSTEMLERİ

Web Uygulamasında Entra ID ile OIDC Oturum Açma ve Token Yönetimi

Entra ID OIDC ile web uygulamasına SSO: authorization code + PKCE, uygulama kaydı, token saklama (BFF), app roles ile yetki, oturum kapatma ve AADSTS hataları.

Bu makalede7 bölüm
Teknik özet
Teknoloji
Microsoft Entra ID, OpenID Connect, OAuth 2.0, PKCE (RFC 7636), MSAL, Microsoft.Identity.Web
Konu
Web uygulamasına kurumsal SSO ve token yönetimi
Seviye
Orta–ileri
Ön koşullar
  • Entra ID’de uygulama kaydı oluşturma yetkisi
  • HTTP yönlendirme ve çerez bilgisi
  • JWT yapısına aşinalık

Kurum içi bir web uygulamasına “Microsoft hesabıyla giriş” eklemek birkaç satır kütüphane yapılandırması gibi görünür. Değildir. Hangi akışın seçildiği, token’ların nerede durduğu ve yetkinin hangi talepten okunduğu uygulamanın güvenlik seviyesini doğrudan belirler. Aşağıda Microsoft Entra ID ile OpenID Connect (OIDC) oturum açmayı baştan sona ele alıyoruz: authorization code + PKCE akışı, uygulama kaydı, token türleri ve saklama, rol tabanlı yetkilendirme, oturum kapatma ve sahada en sık çıkan AADSTS hata kodları.

OIDC ve OAuth 2.0 rolleri

OAuth 2.0 (RFC 6749) bir yetkilendirme çerçevesidir: bir istemcinin kullanıcı adına bir kaynağa erişmesine izin verir. OpenID Connect bunun üzerine bir kimlik katmanı ekler ve istemciye kullanıcının kim olduğunu bildiren ID token’ı tanımlar. Entra ID senaryosunda roller şöyle eşleşir:

Rol Entra ID senaryosunda
OpenID Provider / yetkilendirme sunucusu Microsoft kimlik platformu (login.microsoftonline.com)
Relying Party / istemci Sizin web uygulamanız (uygulama kaydı)
Kaynak sunucusu Kendi API’niz veya Microsoft Graph
Kaynak sahibi Oturum açan kullanıcı

Bu ayrımı netleştirmek, kod incelemesinde en sık gördüğümüz hatayı baştan keser: kimlik doğrulamak (ID token) ile bir API’ye erişim yetkisi almak (access token) farklı işlerdir ve farklı token’larla yapılır. ID token API’ye gönderilmez. Uygulamanın Microsoft Graph’a hangi izinlerle erişeceği ayrı bir tasarım konusu; onu Microsoft Graph API izinleri yazısında anlattık. Buradaki konu kullanıcının uygulamaya giriş akışı.

Authorization code + PKCE akışı

Web uygulamaları için önerilen akış, PKCE (RFC 7636) ile güçlendirilmiş authorization code akışıdır. Eskiden tek sayfa uygulamalarda kullanılan implicit akış token’ı URL parçasında taşıdığı için artık önerilmiyor. Akışın adımları:

  1. Uygulama rastgele bir code_verifier üretir ve bunun SHA-256 özetinin base64url kodlamasını code_challenge olarak hesaplar. Ayrıca CSRF’e karşı state, yeniden oynatmaya karşı nonce değeri üretir ve bunları kullanıcının oturumunda saklar.
  2. Tarayıcı yetkilendirme uç noktasına yönlendirilir (aşağıda URL kodlamalı bir örnek istek var).
  3. Kullanıcı Entra ID’de kimlik doğrular; Koşullu Erişim ilkeleri ve MFA bu aşamada uygulanır.
  4. Entra ID tarayıcıyı kayıtlı yönlendirme URI’sine bir code ve state ile geri gönderir.
  5. Uygulama state değerini doğrular, kodu token uç noktasında code_verifier ve istemci kimlik bilgisiyle token’lara çevirir.
  6. ID token’ın imzası, iss, aud, exp ve nonce değerleri doğrulanır; uygulama kendi oturumunu oluşturur.
GET https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
  ?client_id={client-id}
  &response_type=code
  &redirect_uri=https%3A%2F%2Fportal.ornek.com.tr%2Fsignin-oidc
  &response_mode=form_post
  &scope=openid%20profile%20offline_access
  &state={rastgele-state}
  &nonce={rastgele-nonce}
  &code_challenge={code-challenge}
  &code_challenge_method=S256

Bu adımları elle kodlamayın. Olgun bir kütüphane kullanın: ASP.NET Core için Microsoft.Identity.Web, Node.js için MSAL Node veya standart bir OIDC istemci kütüphanesi. ASP.NET Core’da temel yapılandırma şöyledir:

// Program.cs
builder.Services
    .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

// appsettings.json
"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "TenantId": "{tenant-id}",
  "ClientId": "{client-id}",
  "CallbackPath": "/signin-oidc"
  // Kodu token’a çevirmek ve API çağırmak için istemci kimlik bilgisi
  // "ClientCredentials" altında tanımlanır (sertifika tercih edilir)
}

Kiracı olarak common veya organizations yerine kendi kiracı kimliğinizi yazın. İç uygulamada başka kuruluşların hesaplarıyla giriş denemesi böylece en baştan kapanır.

Uygulama kaydı ve yönlendirme URI’leri

Entra yönetim merkezinde App registrations altında oluşturulan kayıt, uygulamanın kimliğidir. Kurulumda tek tek kontrol edilecek ayarlar:

  • Desteklenen hesap türleri: İç uygulama için “yalnız bu kuruluş dizinindeki hesaplar” (tek kiracı).
  • Platform türü: Sunucu tarafı uygulama için Web; token’ı doğrudan tarayıcıdan alan tek sayfa uygulama için Single-page application. Yanlış platform türü, aşağıdaki hata kodlarının en yaygın sebebidir.
  • Yönlendirme URI’leri: Birebir eşleşme aranır; şema, alan adı, port, yol ve sondaki eğik çizgi dahil. localhost dışında HTTPS zorunludur. Geliştirme, test ve üretim için ayrı kayıt açın; aksi halde üretim kaydında test adresleri unutulur.
  • Implicit grant seçenekleri: Authorization code akışında “ID tokens” ve “Access tokens” onay kutuları işaretsiz kalmalı.
  • İstemci kimlik bilgisi: İstemci sırrı yerine sertifika, mümkünse federated/managed identity tercih edin. Sır kullanıyorsanız son kullanma tarihini bir takvime ve izleme kaydına bağlayın. Süresi dolan sır, bir sabah bütün kullanıcıları dışarıda bırakır.
  • Kullanıcı ataması: Enterprise applications altında “Assignment required?” açıldığında yalnız atanan kullanıcı ve gruplar oturum açabilir.

Token türleri ve güvenli saklama

Token Amaç Kim tüketir
ID token Kullanıcının kimliği ve oturum bilgisi İstemci uygulama
Access token Belirli bir API’ye erişim Hedef API (aud değeri)
Refresh token Kullanıcı etkileşimi olmadan yeni access token almak Yalnız istemci, token uç noktasına gönderir

Microsoft kimlik platformunda access token’ların varsayılan ömrü kısa tutulur ve refresh token ile yenilenir; tek sayfa uygulama platformunda düzenlenen refresh token’ların ömrü daha da kısadır. Bu süreleri Microsoft güncelleyebilir. Kodda sabit süre varsaymayın; expires_in ve exp değerlerini kullanın.

Saklama kararında iki ana desen var:

  • BFF (backend for frontend): Token’lar yalnız sunucuda, oturum deposunda tutulur; tarayıcı yalnız HttpOnly, Secure ve SameSite=Lax (veya Strict) özellikli bir oturum çerezi alır. API çağrıları BFF üzerinden geçer. XSS olsa bile saldırgan token’ı okuyamaz. Kurumsal uygulamalar için varsayılan tercih budur. App Router kullanan Next.js web uygulamalarında bu desen, token’ların yalnız sunucu modüllerinde kalmasıyla kurulur; sınırın nasıl çizileceğini Next.js App Router’da Server ve Client Component ayrımı yazısında anlattık.
  • Tarayıcıda token: MSAL Browser token’ları varsayılan olarak sessionStorage’da tutar. Ayrı bir sunucu katmanı gerekmez; ama sayfada çalışan her betik token’a erişebilir. Bu desen seçilirse içerik güvenlik politikası (CSP), üçüncü taraf betik denetimi ve kısa token ömrü zorunlu hale gelir. localStorage kullanmayın.

Kendi API’niz access token’ı doğrularken şunları karşılaştırmalı: imzayı kiracının JWKS uç noktasından alınan anahtarla, iss değerini kiracınızla, aud değerini API’nin uygulama kimliği/URI’siyle, scp veya roles taleplerini beklenen izinlerle. Kullanıcıyı uygulama veritabanında eşleştirirken e-posta değil, oid ve tid birlikte kullanılır. E-posta değişir; oid değişmez.

Uygulama rolleri ve grup taleplerinden yetkilendirme

Yetkilendirme için iki kaynak var: uygulama rolleri (app roles) ve grup talepleri. Uygulama rolleri kayıt üzerinde tanımlanır (App roles bölümü; örneğin Talep.Olustur, Talep.Onayla, Yonetici), kurumsal uygulama üzerinden kullanıcı veya gruplara atanır ve token’da roles talebi olarak gelir. Rol adları uygulamaya özgü ve anlamlı olduğu için kod okunaklı kalır:

[Authorize(Roles = "Talep.Onayla")]
public IActionResult Onayla(Guid talepId) { ... }

Grup talepleri (Token configuration > Add groups claim) grup nesne kimliklerini taşır. İki sınırlaması var: kodda GUID listesiyle çalışmak zorlaşır ve kullanıcı çok sayıda gruba üyeyse token’a gruplar yerine bir “aşım” (overage) göstergesi konur. JWT’de bu sınır 200 gruptur; aşıldığında uygulamanın grupları Microsoft Graph’tan ayrıca sorgulaması gerekir. Test ortamında üç gruplu bir kullanıcıyla çalışan kod, üretimde yüzlerce gruba üye bir yöneticide kırılır. Tercih sırası bu yüzden net: önce uygulama rolleri; grup şartsa “yalnız uygulamaya atanmış gruplar” seçeneği. Müşteri bazlı yetki gereken portallarda rol modelini veri katmanıyla birleştirmek için B2B portal yetkilendirme mimarisi yazısına bakın.

Oturum kapatma ve sık hatalar

Oturum kapatma iki katmanlıdır: uygulamanın kendi oturum çerezini silmek ve kullanıcıyı Entra ID’nin oturum sonlandırma uç noktasına (/oauth2/v2.0/logout) post_logout_redirect_uri parametresiyle yönlendirmek. Yalnız yerel çerezi silerseniz Entra oturumu açık kalır; kullanıcı “Giriş yap”a bastığında sessizce yeniden içeri alınır. Paylaşılan cihazlarda bu fark ciddi sorundur. Uygulama kaydında bir front-channel logout URL tanımlanırsa, kullanıcı başka bir uygulamadan çıktığında Entra ID bu adresi çağırır ve uygulama yerel oturumu temizleyebilir.

Sahada en sık görülen hata kodları ve anlamları:

Kod Anlam Tipik çözüm
AADSTS50011 Yönlendirme URI’si kayıtla eşleşmiyor Ters vekil arkasında şema/host bilgisini düzeltin, URI’yi birebir ekleyin
AADSTS700054 id_token yanıt türü etkin değil Kütüphaneyi code akışına geçirin
AADSTS65001 Kullanıcı veya yönetici onayı verilmemiş İzinler için yönetici onayı verin
AADSTS50105 Kullanıcı uygulamaya atanmamış Kullanıcıyı veya grubunu uygulamaya atayın
AADSTS7000215 Geçersiz istemci sırrı Sırrın değerini (kimliğini değil) kullanın, süresini kontrol edin
AADSTS9002326 Çapraz kaynak token alımı yalnız SPA türünde mümkün Yönlendirme URI’sini doğru platform türüne taşıyın

AADSTS50011’in en yaygın kaynağı, TLS’in ters vekilde sonlandırıldığı ve uygulamanın kendini http:// üzerinde çalışıyor sandığı kurulumlardır. Uygulama yönlendirme URI’sini http ile üretir, kayıtta https vardır, eşleşme tutmaz. ASP.NET Core’da ForwardedHeaders ara katmanı, Node.js’te vekil güveni (trust proxy) ayarı ile özgün şema ve host bilgisi uygulamaya iletilmelidir. Hata kodunun tam açıklaması için login.microsoftonline.com/error sayfasına kodu girin.

Canlıya almadan önce kontrol listesi:

  • Tek kiracı, doğru platform türü ve ortam başına ayrı uygulama kaydı.
  • state, nonce ve PKCE kütüphane tarafından etkin; implicit grant kapalı.
  • Token’lar BFF’de; tarayıcıda yalnız HttpOnly ve Secure çerez.
  • Kullanıcı eşleştirmesi oid + tid; yetki uygulama rollerinden.
  • Çıkışta hem yerel oturum hem Entra oturumu sonlandırılıyor.
  • İstemci sırrı/sertifika son kullanma tarihi izleniyor.

Oturum açmanın gücü, Entra ID tarafındaki kimlik doğrulama yöntemine bağlıdır; kimlik avına dayanıklı yöntemlere geçiş için FIDO2 ve passkey geçiş planı yazısına bakın. Kurum içi uygulamanıza SSO ve rol tabanlı yetki eklerken akışı ve token saklama desenini özel web uygulaması geliştirme hizmetimiz kapsamında birlikte kurgulayabiliriz. Ayrıntılı başvuru için Microsoft kimlik platformu dokümantasyonu ve RFC 7636 esas alınmalı.

Sık sorulan sorular

Sunucu tarafı bir web uygulamasında da PKCE kullanmak gerekir mi?

Zorunlu değil ama önerilir. İstemci sırrı veya sertifikası kullanan gizli istemcilerde PKCE, yetkilendirme kodunun ele geçirilip başka bir oturumda kullanılmasına karşı ek koruma sağlar. OAuth 2.0 güvenlik en iyi uygulamaları (RFC 9700) gizli istemciler için de PKCE önerir; güncel MSAL kütüphaneleri bunu destekler.

Kullanıcıyı uygulama veritabanında hangi talep ile eşleştirmeliyim?

Kalıcı ve tekil eşleştirme için oid (nesne kimliği) ile tid (kiracı kimliği) birlikte kullanılır. preferred_username, upn veya email değişebilir ya da başka bir kullanıcıya yeniden atanabilir; bunları yalnız görüntüleme için kullanın.

Kullanıcının bir rolden çıkarılması uygulamaya ne zaman yansır?

Roller ve gruplar token düzenlenirken talep olarak yazıldığı için değişiklik, uygulama yeni token alana kadar yansımaz. Uygulama kendi oturum çerezini uzun süre geçerli tutuyorsa gecikme daha da uzar. Hassas yetkilerde oturum süresini kısa tutun veya işlemden önce yeniden kimlik doğrulama isteyin.

Microsoft Graph’tan aldığım access token’ı uygulamada çözüp doğrulamalı mıyım?

Hayır. Microsoft, Graph gibi başka bir kaynak için düzenlenen access token’ların istemci açısından opak kabul edilmesini ve ayrıştırılmamasını önerir; biçimleri haber verilmeden değişebilir. İstemci kullanıcı bilgisini ID token’dan alır; kendi API’niz ise yalnız kendisi için düzenlenmiş access token’ı doğrular.

Teknik özet
Teknoloji
Microsoft Entra ID, OpenID Connect, OAuth 2.0, PKCE (RFC 7636), MSAL, Microsoft.Identity.Web
Konu
Web uygulamasına kurumsal SSO ve token yönetimi
Seviye
Orta–ileri
Ön koşullar
  • Entra ID’de uygulama kaydı oluşturma yetkisi
  • HTTP yönlendirme ve çerez bilgisi
  • JWT yapısına aşinalık
Eretek uzman desteği

Bu konu sizin ortamınızda nasıl çalışır, birlikte bakalım.

Mevcut yapınızı inceliyor, darboğazı tespit ediyor ve uygulanabilir bir iş planı öneriyoruz.