sazak@labs:~
oturum

etiketler

OAuth 2.0ASP.NET CoreZero TrustauthorizationAPI securityJWT

Software · Jun 17, 2026 · 10 dk okuma

ASP.NET Core'da Zero Trust: Authentication'dan Kurumsal API Güvenliğine

ASP.NET Core'da Zero Trust, kullanıcıyı bir kez doğrulayıp güvenmek değil, her istekte kimliği, yetkiyi ve erişilen kaynağı değerlendirmektir. JWT, OAuth 2.0, policy-based authorization ve API güvenliğinin birlikte nasıl çalışması gerektiğini açıklar.

ASP.NET Core'da Zero Trust: Authentication'dan Kurumsal API Güvenliğine

Kurumsal bir ASP.NET Core uygulamasında Zero Trust, her HTTP isteğinin kimliğini doğrulamak ve o isteğin belirli bir kaynak üzerinde gerçekleştirmek istediği işlemi ayrıca yetkilendirmek üzerine kurulmalıdır. Geçerli bir JWT, başarılı bir login veya şirket ağı içinden gelen bağlantı tek başına güven kararı değildir. Güvenlik kararı, doğrulanmış kimlik ile kaynağın güncel erişim kuralları birlikte değerlendirilerek verilir.

Bu ayrım özellikle birden fazla API, kullanıcı rolü ve veri sahipliği modeli bulunan sistemlerde belirleyicidir. Authentication doğru çalışırken bir çalışan başka departmanın kayıtlarını okuyabilir, bir servis gereğinden fazla veri çekebilir veya geçerli token taşıyan saldırgan kritik bir işlemi gerçekleştirebilir. Böyle bir sistemde login mekanizması başarılıdır; güvenlik mimarisi ise başarısızdır.

Authentication kimliği doğrular, authorization erişimi belirler

Authentication, isteği yapan öznenin kim olduğunu veya hangi client adına hareket ettiğini doğrular. Authorization ise bu öznenin belirli bir işlemi gerçekleştirmesine izin verilip verilmediğini belirler. ASP.NET Core bu iki sorumluluğu farklı mekanizmalarla ele alır: authentication handler kimliği oluşturur, authorization sistemi ise policy ve requirement üzerinden erişim kararı üretir.

Bir çalışan kurumsal identity provider üzerinden giriş yaptığında uygulama bir ClaimsPrincipal elde edebilir. ClaimsPrincipal, doğrulanmış kimliğe ilişkin claim değerlerini taşır. sub kullanıcıyı tanımlayabilir, role uygulama rolünü gösterebilir, scope ise token sahibine verilmiş API erişim kapsamını ifade edebilir. Ancak claim, her zaman güncel iş yetkisini temsil etmez.

Örneğin role=Manager claim'i taşıyan bir kullanıcının bütün departmanların bütçe kayıtlarını düzenleyebilmesi gerekmez. Rol, kullanıcının genel sorumluluğunu anlatır; belirli bütçe kaydına erişim hakkı ise kaydın departmanı, durumu ve kullanıcının güncel görevlendirmesine bağlı olabilir.

Burada RBAC, yani Role-Based Access Control, erişim kararlarını rollere bağlayan modeldir. RBAC kurumsal uygulamalarda kullanışlıdır çünkü tekrar eden izinleri merkezileştirir. Ancak rol sayısı büyüdükçe her özel durumu yeni bir role dönüştürmek yönetilemez hale gelir. FinanceManager, RegionalFinanceManager ve benzeri rollerin çoğalması genellikle kaynak düzeyindeki kuralların rol modeline zorla yerleştirildiğini gösterir.

ASP.NET Core'un policy-based authorization yaklaşımı bu sorunu daha kontrollü yönetir. Bir policy, erişim için karşılanması gereken requirement kümesini tanımlar. Örneğin CanApproveExpense policy'si uygun permission claim'ini ve uygulamaya özgü bir kontrolü gerektirebilir. Birden fazla requirement aynı policy içinde tanımlandığında varsayılan yaklaşım bunların tamamının karşılanmasıdır.

Endpoint düzeyinde [Authorize(Policy = "CanApproveExpense")] kullanmak, işlemin genel iznini kontrol eder. Fakat hangi masraf kaydının onaylanabileceğini belirlemek için kayıt verisine de ihtiyaç vardır. Bu nedenle endpoint authorization ile resource-based authorization aynı şey değildir.

Resource-based authorization, erişim kararını yüklenmiş bir domain nesnesi üzerinde verir. Controller veya endpoint önce kaydı bulur; ardından IAuthorizationService aracılığıyla kullanıcının o kaydı onaylamaya yetkili olup olmadığını değerlendirir. Kayıt başka departmana aitse genel onay yetkisi yeterli olmaz.

Bu kontrollerin sırası da önemlidir. Kaydı okumak için kullanılan database sorgusu hassas alanları gereksiz yere belleğe taşımamalı, authorization başarısız olduğunda veri response içine girmemelidir. Kaynak varlığının dahi gizli olduğu sistemlerde 403 yerine 404 döndürmek düşünülebilir; ancak hata mesajları ve response süreleri üzerinden bilgi sızması da değerlendirilmelidir.

Geçerli JWT, güvenilir işlem anlamına gelmez

Zero Trust hakkında yaygın açıklama, her istekte JWT doğrulanmasını güvenliğin merkezi olarak sunar. Bu açıklamanın eksik bıraktığı mekanizma, token geçerliliği ile iş yetkisinin birbirinden farklı yaşam döngülerine sahip olmasıdır. JWT teknik olarak geçerli kalırken kullanıcının departmanı değişebilir, erişimi kaldırılabilir veya ilgili kayıt başka bir çalışana devredilebilir.

JWT, claim taşıyabilen bir token formatıdır; başlı başına authentication protokolü değildir. İmzalı JWT kullanan bir API, token'ın imzasını, beklenen issuer değerini, audience bilgisini ve geçerlilik süresini doğrulamalıdır. İmza doğrulaması token'ın yetkili issuer tarafından üretildiğine ve içeriğinin değiştirilmediğine ilişkin güvence sağlar. Token içindeki bütün iş iddialarının halen doğru olduğunu garanti etmez.

OAuth 2.0, bir client'ın korunan kaynaklara belirli kapsamlarla erişebilmesini sağlayan authorization framework'üdür. OpenID Connect ise OAuth 2.0 üzerine kurulu bir identity layer ekleyerek kullanıcı authentication işlemini standartlaştırır. Bu nedenle access token ile ID token birbirinin yerine kullanılmamalıdır. ID token client'a authentication sonucunu bildirir; API erişim kararının temeli uygun audience'a sahip access token olmalıdır.

ASP.NET Core tarafında AddJwtBearer ile yapılandırılan authentication handler, token doğrulamasını gerçekleştirir. HTTPS metadata kullanımı, doğru authority tanımı ve audience kontrolü önemlidir. Birden fazla issuer kabul ediliyorsa her issuer için güven ilişkisi açıkça tanımlanmalıdır; yalnızca token'ın parse edilebilmesi kabul gerekçesi değildir.

Bearer token'ın temel özelliği, onu ele geçiren kişinin token geçerli olduğu sürece token sahibinin yetkileriyle istek gönderebilmesidir. Bu nedenle kısa access token ömrü, güvenli token storage, uygun refresh token kontrolleri ve gerektiğinde revocation stratejisi birlikte düşünülmelidir. JWT stateless kullanılabilir; ancak bu tercih bütün erişim kararlarının stateless olması gerektiği anlamına gelmez.

Örneğin işten ayrılan bir çalışanın JWT'si henüz expire olmamış olabilir. Yüksek riskli bir ödeme onayı yalnızca token'daki eski permission claim'ine dayanıyorsa erişim kaldırma işlemi gecikmeli uygulanır. Güncel yetkinin zorunlu olduğu işlemlerde authorization sırasında server-side permission kaydı veya güncel resource ilişkisi sorgulanmalıdır.

Bu yaklaşımın maliyeti vardır. Her istekte database sorgusu yapmak latency ve kapasite üzerinde baskı oluşturur. Çözüm, bütün claim kontrollerini database'e taşımak değil, değişme sıklığına ve riskine göre karar vermektir. Düşük riskli listeleme işlemlerinde kısa süreli cache kabul edilebilirken yüksek tutarlı ödeme onaylarında daha güncel kontrol gerekebilir.

Token doğrulaması ile authorization arasında başka bir ayrım daha bulunur: scope, business permission değildir. expenses.write scope'una sahip bir client, masraf API'sine yazma isteği göndermeye genel olarak yetkili olabilir. Ancak belirli bir masrafı onaylama yetkisi ayrıca doğrulanmalıdır. Scope'u doğrudan bütün domain nesneleri üzerinde sınırsız işlem hakkına dönüştürmek, API güvenliğinde sık rastlanan bir tasarım hatasıdır.

Bir masraf onayı endpoint'i güvenlik modelini ortaya çıkarır

Bir kurumsal masraf yönetimi API'sinde POST /api/expenses/{id}/approve endpoint'ini düşünelim. Finance Manager rolündeki çalışan, kendi departmanına ait ve onay bekleyen masrafları onaylayabilir. Kayıt başka departmana aitse veya daha önce onaylanmışsa aynı işlem reddedilmelidir.

İstek geldiğinde ASP.NET Core authentication middleware access token'ı doğrular. Authorization middleware, endpoint üzerinde belirtilen genel policy'yi değerlendirir. Endpoint çalıştığında id üzerinden masraf kaydı yüklenir ve resource-based authorization devreye girer. Böylece kimlik doğrulama, genel permission ve kayıt özelindeki erişim kararı birbirinden ayrılır.

Örnek resource modeli Expense sınıfı olabilir. Bu sınıfta Id, DepartmentId, Status, Amount ve RequestedById alanları bulunur. Authorization handler, kullanıcının department ilişkisini ve onay yetkisini kontrol eder. Masrafı oluşturan kişinin kendi talebini onaylaması yasaksa bu kural da aynı kararın parçası olmalıdır.

Ancak authorization kontrolünden sonra kayıt tekrar değişebilir. İki yönetici aynı masrafı eşzamanlı onaylamaya çalıştığında her ikisi de başlangıçta Pending durumunu okuyabilir. Sadece application memory içindeki kontrol yeterli değildir. Database transaction, optimistic concurrency token veya koşullu update kullanılarak durum değişikliğinin atomik biçimde doğrulanması gerekir.

Örneğin database update işlemi yalnızca Id eşleştiğinde ve Status = Pending olduğunda başarılı olacak şekilde sınırlandırılabilir. Etkilenen satır sayısı sıfırsa işlem yeniden değerlendirilir veya conflict response döndürülür. Bu kontrol authorization'ın yerine geçmez; authorization sonrasında ortaya çıkan yarış durumunu kapatır.

Aynı endpoint'in SQL Injection açısından da korunması gerekir. SQL Injection, saldırganın input değerlerini SQL komutu olarak yorumlatabildiği durumda ortaya çıkar. EF Core üzerinden parametreli sorgular kullanmak temel savunmadır. Raw SQL gerektiğinde kullanıcı input'unu SQL string içine birleştirmek yerine parameterization uygulanmalıdır.

Frontend tarafında masraf açıklaması gibi kullanıcı tarafından oluşturulmuş alanlar XSS riski taşır. XSS, güvenilmeyen içeriğin tarayıcıda script olarak çalıştırılmasıdır. Razor'ın varsayılan HTML encoding davranışı bu riski azaltır; ancak Html.Raw gibi mekanizmalarla güvenilmeyen içeriği doğrudan HTML olarak üretmek korumayı aşabilir. HTML kabul edilmesi gerekiyorsa güvenilir sanitization politikası gerekir.

CSRF farklı bir saldırı yüzeyidir. Tarayıcının otomatik gönderdiği cookie ile authentication yapılan uygulamalarda saldırgan başka bir siteden state-changing request tetiklemeye çalışabilir. ASP.NET Core antiforgery koruması ve uygun SameSite cookie ayarları bu modelde önemlidir. Authorization header içinde açıkça gönderilen bearer token kullanan API'lerde klasik cookie tabanlı CSRF mekanizması aynı şekilde işlemez; fakat token cookie içinde taşınıyorsa risk yeniden değerlendirilmelidir.

Bu örnek audit logging ihtiyacını da gösterir. Başarılı onay için kimlik, kaynak ID'si, işlem türü, zaman ve sonuç kaydedilmelidir. Reddedilen kritik işlemler de uygun ayrıntıyla izlenmelidir. Audit log yalnızca hata ayıklama kaydı değildir; sonradan hangi yetkiyle hangi kaydın değiştirildiğini araştırabilmenin temelidir.

Log kayıtlarında access token, parola, secret veya gereksiz kişisel veri bulunmamalıdır. Correlation ID, dağıtık servisler arasında işlemi takip etmeyi kolaylaştırır. Audit kayıtlarının erişimi sınırlandırılmalı ve değiştirilmesine karşı koruma sağlanmalıdır. Aksi halde saldırganın değiştirebildiği log, güvenilir kanıt niteliğini kaybeder.

API güvenliği token kontrolünden daha geniştir

OWASP Top 10, web uygulamalarında yaygın güvenlik risklerini sınıflandıran bir referanstır. Ancak listedeki maddeleri tek tek işaretlemek güvenli bir API üretmez. Kurumsal sistemlerde riskler çoğunlukla authentication, authorization, input handling, configuration ve bağımlılık yönetimi arasındaki boşluklarda ortaya çıkar.

API endpoint'lerinin tamamı varsayılan olarak korumalı tasarlanmalıdır. ASP.NET Core'da fallback authorization policy kullanmak, [Authorize] eklenmesi unutulan endpoint'lerin yanlışlıkla açık kalmasını önleyebilir. Health check veya public authentication callback gibi gerçekten anonim erişim gerektiren endpoint'ler açıkça ayrılmalıdır.

Bunun yanında Broken Object Level Authorization olarak bilinen BOLA riski özellikle önemlidir. Saldırgan kendi erişebildiği /api/expenses/100 adresindeki ID değerini başka bir kaydın ID'siyle değiştirerek veri okumaya çalışabilir. JWT doğrulaması bu saldırıyı engellemez. Koruma, her kayıt erişiminde ownership veya ilgili business authorization koşulunun uygulanmasıdır.

Input validation da tek başına güven sınırı değildir. Request schema, veri tiplerini ve beklenen alanları sınırlayabilir; ancak geçerli biçimde gönderilen bir ID yine de başka bir kullanıcıya ait olabilir. Ayrıca entity nesnelerini doğrudan request body'ye bind etmek mass assignment riskine yol açabilir. Güncellenmesine izin verilen alanlar için ayrı request DTO kullanılması daha güvenlidir.

SSRF, yani Server-Side Request Forgery, uygulamanın saldırgan tarafından belirlenen bir adrese server tarafından istek göndermesiyle oluşur. Örneğin masraf sisteminin dış URL'den fatura indirmesine izin verildiğinde saldırgan internal service adreslerini hedefleyebilir. URL validation tek başına yeterli değildir; izin verilen hedeflerin sınırlandırılması, redirect kontrolü ve outbound network kısıtları birlikte uygulanmalıdır.

Rate limiting, otomatik denemeleri ve kaynak tüketimini sınırlamak için kullanılır. ASP.NET Core'un rate limiting middleware'i endpoint veya policy düzeyinde sınır tanımlamaya izin verir. Login, password reset ve pahalı raporlama endpoint'leri farklı politikalara ihtiyaç duyabilir. Ancak rate limiting authorization kontrolünün yerine geçmez ve dağıtık sistemlerde instance başına tutulan sayaçlar toplam trafik sınırını garanti etmez.

Sensitive data protection için encryption hem veri aktarımında hem de saklama aşamasında düşünülmelidir. HTTPS/TLS, client ile server arasındaki aktarımı korur; reverse proxy ile uygulama arasındaki bağlantının nasıl güvence altına alındığı ayrıca değerlendirilmelidir. Database encryption, disk veya backup ele geçirildiğinde riski azaltabilir; ancak uygulamanın yetkili olarak çözebildiği veriye aşırı yetkili bir hesabın erişmesini engellemez.

Parolalar geri çözülebilir encryption ile saklanmamalıdır. Uygun password hashing algoritması ve salt kullanılmalıdır. ASP.NET Core Identity'nin password hashing mekanizması, kendi kriptografik şemasını tasarlamaktan daha güvenli bir başlangıç noktasıdır.

Secret management ayrı bir sorumluluktur. Database password, signing key ve API key gibi değerler source control içine yazılmamalıdır. Development ortamında User Secrets kullanılabilir; production ortamında kontrollü erişim sağlayan secret manager veya managed identity tercih edilmelidir. Secret rotation planı olmayan bir sistem, sızan credential'ların etkisini gereksiz yere uzatır.

Encryption key yönetimi de encryption algoritması kadar önemlidir. Anahtarlar uygulama verisiyle aynı erişim sınırı içinde korunuyorsa veri sızıntısı sırasında ikisinin birlikte ele geçirilmesi mümkündür. Key erişimi sınırlandırılmalı, rotation ve recovery süreçleri önceden belirlenmelidir.

Zero Trust kararını kaynak ve işlem düzeyinde verin

ASP.NET Core için savunulabilir başlangıç mimarisi, OpenID Connect üzerinden kullanıcı authentication işlemini merkezi identity provider'a bırakmak, API'lerde OAuth 2.0 access token doğrulamak ve authorization kararlarını uygulamanın gerçek business kurallarıyla birleştirmektir. Endpoint düzeyinde policy-based authorization genel izinleri kontrol etmeli; belirli kayıtlar üzerindeki işlemler resource-based authorization ile sınırlandırılmalıdır.

Bu modelde RBAC tamamen kaldırılmaz. Roller geniş sorumluluk alanlarını ifade eder, permission ve policy mekanizmaları işlemleri sınırlar, resource authorization ise belirli kaydın erişilebilir olup olmadığını belirler. Böylece her özel durum için yeni rol üretmek gerekmez.

Benim tercih edeceğim güvenlik sınırı, yüksek etkili bir işlemin yalnızca JWT claim'lerine dayanarak tamamlanmamasıdır. Para transferi, ödeme onayı, yetki değişikliği veya hassas veri dışa aktarma gibi işlemlerde güncel server-side authorization ve transaction düzeyinde tutarlılık kontrolü gerekir. Bu karar ek database erişimi ve latency getirebilir; fakat eski token içeriğine güvenmenin doğurduğu yetki açığı çoğu kurumsal sistemde daha ağırdır.

Bu tercih her endpoint için aynı maliyeti haklı çıkarmaz. Public içerik sunan, kişisel veri taşımayan veya yetkileri token ömrü boyunca değişmeyen düşük riskli servislerde JWT claim'leriyle verilen kararlar yeterli olabilir. Kaynak sahipliği bulunmayan machine-to-machine API'lerde de resource-based authorization her zaman gerekli değildir; doğru audience, scope ve client permission sınırları ön plana çıkar.

Uygulama sürecinde önce korunacak varlıklar ve işlemler belirlenmelidir. Ardından her endpoint için hangi identity'nin kabul edildiği, hangi permission'ın gerektiği ve hangi resource koşulunun uygulanacağı açıkça yazılmalıdır. Bu kurallar integration test içinde farklı kullanıcı, farklı departman, iptal edilmiş yetki ve eşzamanlı işlem senaryolarıyla doğrulanmalıdır.

En az bir test, geçerli token taşıyan fakat ilgili kaynağa erişim hakkı bulunmayan identity'nin reddedildiğini kanıtlamalıdır. Çünkü Zero Trust'ın ayırt edici sınaması geçersiz token'ı reddetmek değildir. Geçerli kimliğin yetkisiz işlemini durdurabilmektir.

yorumlar

0

Henüz yorum yok. İlk notu sen bırak.

Yorum yazmak için giriş yap.

Gmail ile saniyeler içinde, ya da e-posta ile kaydol.

bağlı 26109:32:57