Spring Security ile giriş ve yetki kontrolü nasıl kurulur
Beceri rehberi

Spring Security ile giriş ve yetki kontrolü nasıl kurulur

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Spring Security'de filtre zinciri, parola saklama, JWT tabanlı kimlik doğrulama ve rol bazlı yetkilendirmeyi adım adım nasıl kuracağınızı öğrenin.

Kimlik doğrulama ve yetkilendirme farkı

Kimlik doğrulama (authentication) 'sen kimsin' sorusunun yanıtıdır: kullanıcı adı ve parola, bir belirteç ya da bir dış kimlik sağlayıcısı ile doğrulanır. Yetkilendirme (authorization) ise 'bunu yapmaya iznin var mı' sorusudur: doğrulanmış kullanıcının rolüne ve izinlerine bakılır. Bu işleri aynı kod bloğunda karıştırmak, güvenlik açıklarının en sık görülen kaynağıdır.

Spring Security bu işleri bir filtre zinciri üzerinden yürütür. Her gelen istek, controller'a ulaşmadan önce sıralı güvenlik filtrelerinden geçer: biri isteğin kimlik bilgisini okur, biri kimliği doğrular, biri yetkiyi denetler, biri hataları uygun yanıta çevirir. Bu yapıyı anlamadan örnek kod kopyalamak, neden istek reddedildiğini çözemeyeceğiniz durumlar yaratır.

Başlangıç: bağımlılığı eklemek ve varsayılan davranışı görmek

Projeye güvenlik starter'ını eklediğiniz anda tüm adresler korumaya alınır; Spring Boot rastgele bir parola üretir ve günlüğe yazar. Bu davranış bilerek kısıtlayıcıdır: güvenliği sonradan açmak yerine baştan kapalı başlatır.

Güvenliği kendi gereksiniminize göre yapılandırmak için bir SecurityFilterChain tanımı yazarsınız:

@Bean SecurityFilterChain chain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(a -> a .requestMatchers("/api/open/*").permitAll() .requestMatchers("/api/admin/*").hasRole("ADMIN") .anyRequest().authenticated()) .csrf(c -> c.disable()); return http.build(); }

Bu örnekte açık adresler herkese, yönetim adresleri yönetici rolüne açık; geri kalan her şey giriş gerektirir. Kuralların sırası önemlidir: daha özel kuralı genel kuraldan önce yazın. CSRF korumasını kapatmak, yalnızca tarayıcı çerezi kullanmayan, belirteç tabanlı API'lerde uygundur; çerez tabanlı oturum kullanıyorsanız kapatmayın.

Parolayı doğru saklamak

Parolayı veri tabanında asla düz metin ya da hızlı bir özet fonksiyonuyla saklamayın. Spring Security'nin PasswordEncoder arayüzü bu iş için vardır; yaygın tercih BCrypt tabanlı kodlayıcıdır. Yeni kullanıcı kaydında parolayı kodlayıp kaydedersiniz, girişte ise düz parolayı kodlayıcının eşleşme metodu ile saklanan özetle karşılaştırırsınız.

Kullanıcıyı veri tabanından yüklemek için UserDetailsService gerçeklemesi yazın: kullanıcı adına göre kayıt bulur, parola özeti ve rolleri içeren bir UserDetails döndürür. Kullanıcı bulunamazsa özel bir istisna fırlatırsınız; mesajda 'kullanıcı yok' ya da 'parola yanlış' ayrımını dışarıya vermemek, kullanıcı adı taramasını zorlaştırır.

Başarısız giriş denemelerine sınır koymak ve hesap kilitleme politikasını belirlemek, kaba kuvvet saldırılarını yavaşlatır. Bu politikayı iş tarafıyla birlikte netleştirin, çünkü kilitleme hizmet reddine de yol açabilir.

Belirteç (JWT) tabanlı kimlik doğrulama akışı

Durumsuz (stateless) bir API'de sunucu oturum tutmaz; her istek kimliğini bir belirteçle taşır. Tipik akış şöyledir:

  • Kullanıcı giriş adresine kimlik bilgisini gönderir.
  • Sunucu bilgileri doğrular ve imzalı bir belirteç üretir; belirteç kullanıcı kimliğini, rolleri ve bitiş zamanını taşır.
  • İstemci sonraki isteklerde belirteci yetkilendirme başlığında gönderir.
  • Zincire eklenen özel bir filtre başlığı okur, imzayı ve süreyi doğrular, geçerliyse güvenlik bağlamına kimliği yerleştirir.

Belirteç yaşam süresini kısa tutun; uzun süreli oturum için ayrı bir yenileme belirteci kullanın ve onu sunucu tarafında iptal edilebilir biçimde saklayın. İmza anahtarını koda gömmeyin, ortam değişkeni ya da gizli yönetim aracından okuyun. Belirteç içine parola ya da hassas kişisel veri koymayın, çünkü belirtecin içeriği şifreli değil yalnızca imzalıdır. Kendi JWT filtrenizi yazmadan önce, Spring Security'nin kaynak sunucu desteğinin gereksiniminizi karşılayıp karşılamadığına bakın; hazır destek, imza doğrulama gibi hataya açık işleri sizin yerinize yapar.

Rol ve izin bazlı yetkilendirme

URL bazlı kurallar kaba yetkilendirme sağlar. İnce ayar için metot düzeyinde güvenliği açın ve servis metotlarında @PreAuthorize kullanın:

@PreAuthorize("hasRole('MANAGER') or #customerId == authentication.name") CustomerDetail get(String customerId) { ... }

Burada yetki, çağrılan parametreye göre dinamik hesaplanıyor: yönetici herkesin kaydını, normal kullanıcı yalnızca kendi kaydını görebiliyor. Bu tür 'nesne düzeyi' kontrol atlandığında, kullanıcı başkasının kaydının kimliğini adreste değiştirerek erişebilir; bu, API güvenliğinde en yaygın zafiyet sınıflarından biridir. Yetkilendirme kuralını controller'a değil, veriye erişimin yapıldığı servise koyun ki aynı kural her giriş noktasında geçerli olsun.

Rol sayısı arttıkça rolleri 'ne yapabilir' sorusuna dönüşen izinlerle (okuma, yazma, onaylama) ifade etmek, uzun vadede daha yönetilebilirdir.

Test ve doğrulama

Güvenlik kurallarını elle denemek yetmez; her kuralın testi olmalıdır. Spring Security test desteği ile sahte bir kullanıcı ya da rol tanımlayarak MockMvc ile istek atabilirsiniz. Şu senaryoları mutlaka karşılayın: kimliksiz istek reddedilir, yanlış rolle istek reddedilir, doğru rolle istek başarılı olur, başkasının kaynağına erişim reddedilir, süresi dolmuş belirteç reddedilir.

Güvenlik testleri değişiklik sırasında kurallardan birini yanlışlıkla açtığınızda sizi uyarır. Bir de olumsuz test alışkanlığı edinin: 'doğru kullanıcı girebiliyor' kadar 'yanlış kullanıcı giremiyor' testini de yazın. Ayrıca bağımlılıkların bilinen açıklarını düzenli tarayın ve güvenlik başlıklarının (içerik güvenlik politikası, çerçeve engelleme gibi) istenen şekilde döndüğünü yanıt üzerinde kontrol edin.

Sık yapılan hatalar

  • Her şeyi izinli bırakıp sonradan kısmak. Önce kapalı başlayın, gerekeni açın.
  • Parolayı hızlı özet fonksiyonuyla saklamak ya da kodlayıcıyı hiç kullanmamak.
  • JWT imza anahtarını depoya koymak.
  • Yetkiyi yalnızca ön yüzde gizlemek. API her zaman kendi denetimini yapmalı.
  • CSRF korumasını, çerez kullanılan bir uygulamada kapatmak.
  • Nesne düzeyi yetki kontrolünü atlamak. Rol doğru olsa da kaynak kullanıcıya ait olmayabilir.
  • Hata mesajlarında hangi bilginin yanlış olduğunu açıkça söylemek.
  • Belirteç süresini çok uzun tutmak ve iptal mekanizması bırakmamak.
  • Güvenlik yapılandırmasını kopyala yapıştır alıp anlamadan kullanmak. Eski örneklerde artık kullanılmayan yapılandırma biçimleri bulunabilir; sürümünüzün belgesine bakın.

Bu beceriyi Mindset programlarında nerede çalışırsınız?

Java Spring Boot ile Backend programında Spring Security ile güvenlik ayrı bir modül olarak yer alıyor; programın Spring Core ve Web MVC modüllerini tamamlamış geliştiriciler için sıradaki adım gibi duruyor. Kurumsal bir ekipte bu çalışma, servisler arasında ortak bir kimlik doğrulama ve yetki standardı oluşturmak isteyen backend ve platform ekipleri için uygun.

API tarafındaki tehdit sınıflarını Spring'den bağımsız olarak incelemek isteyenler için API Güvenliği ve OWASP API Top 10 programı bu sayfanın konusuna tamamlayıcı olabilir.

İlgili Mindset programı

Java Spring Boot ile Backend

Sık sorulanlar

Sık sorulan sorular

Spring Security öğrenmeden önce neyi bilmeliyim?

Spring Boot'un temelini, HTTP istek-yanıt döngüsünü ve bağımlılık enjeksiyonunu bilmek yeterlidir. Güvenlik tarafında kimlik doğrulama ile yetkilendirme farkını, parola özetleme ve belirteç kavramlarını önceden okumak, filtre zincirini anlamayı çok kolaylaştırır.

JWT mi oturum çerezi mi kullanmalıyım?

Tarayıcı tabanlı, tek alan adlı uygulamalarda sunucu tarafı oturum ve çerez basit ve güvenlidir. Mobil istemciler, birden çok servis ya da durumsuz API için belirteç uygundur. Belirteç iptali ve saklama yeri gibi sorumluluklar size geçtiği için seçimi gerçek ihtiyaçla yapın.

@PreAuthorize çalışmıyor, neden?

Metot düzeyinde güvenlik açıkça etkinleştirilmelidir. Ayrıca anotasyon, Spring'in oluşturduğu proxy üzerinden çağrılan metotlarda çalışır; aynı sınıf içinden yapılan çağrılarda devreye girmez. Anotasyonun bir Spring bileşeninde olduğunu ve dışarıdan çağrıldığını kontrol edin.

OAuth ile giriş eklemek zor mu?

Spring Security, dış kimlik sağlayıcılarıyla giriş ve kaynak sunucu için hazır destek sunar. Yapılandırma görece kısadır ama kapsam, geri çağrı adresi ve kullanıcı eşleme kararlarını doğru vermek gerekir. Önce sağlayıcının belgesini ve Spring sürümünüzün belgesini birlikte okuyun.

Spring Security ile Kimlik Doğrulama ve Yetkilendirme