Bu makalede7 bölüm
- 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ı:
- Uygulama rastgele bir
code_verifierüretir ve bunun SHA-256 özetinin base64url kodlamasınıcode_challengeolarak hesaplar. Ayrıca CSRF’e karşıstate, yeniden oynatmaya karşınoncedeğeri üretir ve bunları kullanıcının oturumunda saklar. - Tarayıcı yetkilendirme uç noktasına yönlendirilir (aşağıda URL kodlamalı bir örnek istek var).
- Kullanıcı Entra ID’de kimlik doğrular; Koşullu Erişim ilkeleri ve MFA bu aşamada uygulanır.
- Entra ID tarayıcıyı kayıtlı yönlendirme URI’sine bir
codevestateile geri gönderir. - Uygulama
statedeğerini doğrular, kodu token uç noktasındacode_verifierve istemci kimlik bilgisiyle token’lara çevirir. - ID token’ın imzası,
iss,aud,expvenoncedeğ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.
localhostdışı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,SecureveSameSite=Lax(veyaStrict) ö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.localStoragekullanmayı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,nonceve PKCE kütüphane tarafından etkin; implicit grant kapalı.- Token’lar BFF’de; tarayıcıda yalnız
HttpOnlyveSecureç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.
- 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
Modern Web Uygulamaları