
Geçen sene bir e-ticaret müşterisinde işe başladığımda, log kayıtları arasında ilginç bir desen vardı: kullanıcılar kayıt oluyor, e-postayı doğruluyor, sonra giriş ekranında takılıyordu. Sebep? MFA’yı her girişte zorunlu kılmışlardı. Müşteri “güvenlik” diye sevinmişti ama dönüşüm oranı yüzde 22 düşmüştü. Sepetteki insanlar kaybolmuştu. İşte Azure AD B2C’nin tam da bu hassas dengeyi ayarlamak için var olduğunu anlatmak için sizinle birkaç notumu paylaşayım.
Önce sık karıştırılan bir noktayı netleştirelim — çünkü ekiplerin yarısı bu yüzden yanlış başlıyor. Azure AD (artık Microsoft Entra ID) kurumsal kimlik içindir; çalışanınız, iş ortağınız, kurumsal SaaS uygulamanız orada. Azure AD B2C ise müşteriniz içindir. Mobil uygulamanızın kullanıcısı, e-ticaret sitenizin abonesi, B2C SaaS müşteriniz. İki sistem ayrı tenant’larda çalışır — ve bu ayrım tesadüf değil; güvenlik açısından doğrusu da budur. Müşteri hesabı kurumsal dizinle aynı yerde durmamalı.
İlk durak: User Flow’lar
Azure AD B2C’ye girdiğinizde portalda karşınıza User Flow’lar çıkıyor. Bunlar Microsoft’un hazır servis ettiği kimlik akışları: kayıt-giriş, profil düzenleme, şifre sıfırlama. Hiç kod yazmadan, dropdown ve checkbox’larla kuruyorsunuz.
İlk projelerde — ve aslında pek çok orta ölçekli projede — User Flow’lar yetiyor. “E-postayla kayıt olsunlar, e-postayı doğrulasınlar, sonra Google ile de giriş yapabilsinler, şifre unuttu işlesin” — bu senaryoyu User Flow ile yarım günde kuruyorsunuz. Geliştirici tarafında MSAL kütüphanesini ekleyip bağlıyorsunuz, oluyor.
Ama gün geliyor şöyle bir istek geliyor: “Kayıt olurken TC kimlik numarasını harici bir API’ye soralım, gerçek mi diye doğrulayalım, sonra kabul edelim.” Veya: “Yeni cihazdan giriş yapılıyorsa MFA istesin, eski cihazdansa istemesin.” İşte burada User Flow yetmiyor — Custom Policy zamanı geliyor.
Custom Policy: Diktir ama açabildiği kapı geniş
Custom Policy XML tabanlı yapılandırma. Identity Experience Framework (IEF) starter pack’inden başlıyorsunuz — Microsoft GitHub’da yayınlamış. İlk iki gün başınızı tutarsınız: trustFrameworkBase.xml, trustFrameworkExtensions.xml, signup_signin.xml… dosyalar birbirine miras veriyor, technical profile’lar zincirleniyor, claim’ler oradan oraya geçiriliyor.
Bir sigorta projesinde Custom Policy ile şöyle bir akış kurmuştuk: kullanıcı normal giriş yaptıktan sonra, eğer müşteri portalına yönleniyorsa, ek olarak poliçe numarasını giriyor; sistem arka planda RESTful technical profile ile sigorta CRM’ine gidiyor; doğrulanırsa giriş tamamlanıyor. Bu adım User Flow’da mümkün değil; Custom Policy ile bir gün içinde yazıldı.
Burada uyarayım: Custom Policy’ye geçtiğiniz an User Flow’lardan vazgeçiyorsunuz. İkisini birlikte kullanmak teknik olarak mümkün ama yönetim kâbusu. Bir kere Custom Policy’ye geçtiyseniz, tüm akışlarınızı oraya taşıyın.
Sosyal hesaplar — kullanıcının kazandırdığı saniyeler
Google, Facebook, Apple, Twitter (X), Microsoft hesabı — beş ana sağlayıcıyı çok kolay ekliyorsunuz. Daha ötesi için OpenID Connect veya SAML 2.0 destekleyen herhangi bir IdP eklenebilir. Kurumsal müşteriniz kendi Active Directory’siyle giriş yapsın istiyorsa bu da mümkün.
Bir SaaS platformunda yaptığımız A/B testte sonuç şuydu: sadece e-posta-şifreli kayıt akışı ile sosyal hesap eklenmiş akış arasında, kayıt tamamlama oranı yüzde 27 farklıydı. Kullanıcının cebine atılmış küçük bir kolaylık, çevrim oranını ciddi ciddi değiştiriyor. Hangi sosyal sağlayıcı olduğu da önemli — Türkiye için Google ve Apple genellikle ilk ikiyi alıyor; Facebook eskisi kadar tıklanmıyor; Twitter’ı koymasanız da olur (artık).
MFA: Her girişte değil, riskliyse
Yazıya girizgâhta anlattığım e-ticaret vakasına dönelim. “Her girişte MFA” yaklaşımı kurumsal senaryolarda mantıklı (zaten çalışan, zaten kuruma bağlı), ama B2C’de müşteriyi kaybediyor. Bizim çözüm: Conditional MFA. Yeni cihazdan giriş varsa, yeni IP veya yeni ülkeden giriş varsa, hassas işlem yapılıyorsa (ödeme, profil değiştirme) MFA tetikleniyor. Günlük standart girişlerde tetiklenmiyor.
MFA yöntemleri: SMS (en yaygın ama en zayıfı — SIM swap riski), e-posta kodu, authenticator uygulaması (Microsoft, Google), TOTP. Tercihim authenticator uygulaması. Maliyeti yok (SMS’in aksine), kullanıcı bir kez kurduktan sonra hızlı, güvenliği SMS’ten ciddi anlamda yüksek. Müşterinizi authenticator’a yönlendirebiliyorsanız hem para hem güvenlik kazanırsınız.
Sayfayı kendi markanıza giydirmek
Varsayılan B2C sayfaları Microsoft markalı — login.microsoftonline.com gibi bir URL’de açılıyor, hatta kendi domain’inize custom domain ile bile bağlasanız sayfa stili Microsoft’un. Bu B2C için iyi değil; müşteri “ben senin sitendeyim, niye Microsoft logosu görüyorum?” diye sorabiliyor.
Çözüm: HTML/CSS template özelleştirme. Kendi HTML şablonunuzu Azure Blob veya CDN’de barındırırsınız, B2C bu şablonu yükleyip içine login bileşenlerini yerleştirir. Tam markalı görüntü elde edersiniz. Bir miktar HTML/CSS bilgisi yetiyor; karmaşık bir iş değil ama UX ekibinizin gözden geçirmesi güzel olur — tek bir sayfa form akışını dakikalarca etkileyebiliyor.
JavaScript de ekleyebiliyorsunuz ama dikkat: B2C sayfasında çalışan JS, kullanıcı kimlik bilgilerine yakın olduğundan kısıtlamalar var. Örneğin doğrudan parola alanını manipule edemiyorsunuz. Bu güvenlik için doğru bir kısıtlama.
Token, scope, ve API koruması
B2C kimlik doğrulaması başarılı olduğunda üç JWT döner: ID token (kullanıcı kim), access token (API’ye gidip ne yapabilir), refresh token (sürelerinin bitince yeni almak için). ID ve access token tipik olarak 1 saat, refresh 14 gün geçerli (ayarlanabilir, max 90 gün).
Bankacılık uygulamalarında token sürelerini kısaltıyoruz (15-30 dakika). E-ticarette bu şart değil — bir saat genelde dengelidir. Refresh token rotation muhakkak açık olsun: her kullanımda eski refresh geçersiz oluyor, yeni veriliyor; çalınmış token’ın uzun süre kullanılmasını engelliyor.
API tarafında scope mekanizması işin tuzu biberi. profile.read, orders.read, orders.write, admin.all gibi scope’lar tanımlıyorsunuz. İstemci uygulama token isterken hangi scope’lara ihtiyacı olduğunu söylüyor, kullanıcı consent veriyor (ya da daha doğrusu, çoğu B2C senaryosunda otomatik onaylı sayılıyor), token o scope’larla geliyor. API tarafında middleware (örneğin .NET’te Microsoft.Identity.Web veya Node’da passport-azure-ad) bu scope’ları doğruluyor. Yetkin yoksa 403.
MSAL: Geliştirici dostu kütüphane
Uygulamanıza B2C entegrasyonunda Microsoft Authentication Library (MSAL) kullanın. JavaScript, React, Angular, .NET, Java, Python, iOS, Android — hepsi var. Token alımı, önbellek, otomatik refresh, hata yönetimi — bunları sizin için hallediyor.
React örneği: @azure/msal-react paketini ekliyorsunuz, B2C tenant ve policy bilgilerinizi config’e koyuyorsunuz, MsalProvider ile uygulamayı sarıyorsunuz. useMsalAuthentication ile login/logout, useAccount ile kullanıcıyı çekiyorsunuz. Token alırken acquireTokenSilent çalıştırıyorsunuz — önce cache’e bakıyor, yoksa refresh token ile sessizce alıyor; başarısız olursa acquireTokenRedirect‘e fallback edip kullanıcıyı login’e yönlendiriyor. Bu pattern uygulamanın her yerinde işliyor.
Eski sistemden göç: Bir e-ticaret hikâyesi
Bir e-ticaret platformunu B2C’ye taşırken 1.4 milyon kullanıcı vardı. Şifreler eski sistemde bcrypt hash’liydi; B2C’ye doğrudan aktarılamıyor (Azure AD farklı hash algoritması bekliyor). İki yol var:
Toplu göç (bulk migration): Microsoft Graph API üzerinden tüm kullanıcıları B2C’ye yazıyorsunuz, ama şifreler taşınmıyor — kullanıcılar ilk girişte “şifre sıfırla” akışından geçmek zorunda. 1.4 milyon kullanıcının yarısı muhtemelen bir daha hiç giriş yapmayacak; bu yöntem onları tamamen kaybetmenize neden olur.
Kademeli göç (just-in-time / seamless): Custom Policy ile login akışında bir kontrol koyuyorsunuz: kullanıcı B2C’de mi var? Yoksa eski sistemin REST API’sine gidiyor, oradaki bcrypt ile şifre doğrulanıyor; doğruysa B2C’de o anda hesap oluşturuluyor, yeni şifre Azure’un beklediği formata yazılıyor, sonraki girişlerde doğrudan B2C üzerinden ilerliyor. Kullanıcı hiçbir şeyin değiştiğini fark etmiyor.
Bizim seçimimiz ikincisiydi. Üç ay içinde aktif kullanıcıların yaklaşık yüzde 60’ı doğal olarak göç oldu. Geri kalan inaktiflere ne yaptık? Hiçbir şey — onlar zaten kaybedilmiş kullanıcılar. Eski sistemdeki kayıtları arşivledik, B2C’ye yük olmadan dururlar.
İzleme ve uyarı: Saldırı sinyallerini erken yakalamak
B2C’yi Azure Monitor ve Log Analytics’e bağlayın. Authentication başarı/başarısızlık oranı, hangi sosyal sağlayıcı ne kadar tıklanıyor, coğrafi dağılım, saatlik trend — bunlar pazarlama için bile değerli.
Güvenlik tarafında üç tane alert kuralım var her projede: (1) Aynı IP’den dakikada 10’dan fazla başarısız login → muhtemel brute-force; (2) Yeni kayıt sayısında ani sıçrama → muhtemel bot saldırısı; (3) Token validation hataları sayısında patlama → token endpoint manipülasyon denemesi olabilir. Bu üçü tetiklendiğinde Slack’e ya da Teams’e bildirim düşüyor, biz bakıyoruz.
Fiyat: Aslında çok cömert
B2C fiyatlandırmasını ilk gördüğümde tekrar baktım, doğru okuduğuma emin olmak için. Aylık ilk 50.000 authentication ücretsiz. Üzerinde, MFA’sız her bin authentication için ~0,003 USD; MFA’lı için ~0,03 USD. Depolama yok, kullanıcı sayısına göre yok. Bir milyon kayıtlı kullanıcısı olan ama ayda 80.000 kişi giriş yapan bir e-ticaret için ayda 0 USD ödüyorsunuz. Cidden 0.
Premium P1 ve P2 tarafları daha kurumsal — koşullu erişim politikaları, identity protection, gelişmiş raporlar geliyor. B2B/kurumsal scenario’larda gerekiyor; saf B2C’de standart B2C tier yetiyor genelde.
Sonuç
Azure AD B2C’yi, kendi kimlik altyapınızı yazma külfetinden ve riskinden kurtulmanın güvenilir yolu olarak görüyorum. User Flow ile başlayın, hız kazanın; gereksinim büyürse Custom Policy ile derine inin; MFA’yı koşullu yapın, kullanıcı kaybetmeyin; eski sistemden geçişte kademeli göçü tercih edin. Bunları yaptığınızda, müşterilerinize hem güvenli hem de pürüzsüz bir kimlik deneyimi sunmuş olursunuz — ve Microsoft’un binlerce mühendisi sizin yerinize güvenlik patch’i geçer.
CloudSpark kimlik ve erişim yönetimi hizmetleri kapsamında Azure AD B2C kurulumu, Custom Policy geliştirme, marka özelleştirme ve kullanıcı göçü projelerinde ekiplerle çalışıyoruz.



