İçeriğe geç
erdem6
Tüm yazılar
·2 dk okuma

Spring Boot & Spring Security ile Dağıtık Mikroservis Güvenliği

Java Spring mikroservis mimarilerinde güvenliğin gerçekte nasıl uygulandığına dair bir içerik analizi — API gateway'den servisler arası güvene kadar.

MikroservisSpring SecurityAraştırmaJava

Mikroservisler bir ölçeklenme sorununu çözer ve bir güvenlik sorunu yaratır. Bir monolit, bağımsız olarak dağıtılan onlarca servise bölündüğü anda ağ, güven sınırının bir parçası hâline gelir — ve çoğu ekip bunu zor yoldan öğrenir.

Bu yazı, Java Spring mikroservislerinin güvenliği üzerine 10+ akademik ve endüstriyel kaynak üzerinde yürüttüğüm içerik analizinin bir özeti. Tek bir öğreticiyi tekrarlamak yerine, literatürde tekrar eden desenlere, kaynakların hemfikir olduğu ve sessizce çeliştiği noktalara baktım.

Problemin şekli

Bir mikroservis sistemine giren istek, birden çok güven geçişinden geçer:

  • Dış dünya → Gateway. Dışarısı tek bir giriş noktasına ulaşır.
  • Gateway → Servis. Gateway, kimliği doğrulanmış ve yetkilendirilmiş çağrıyı iletir.
  • Servis → Servis. İç çağrılar dağılır, çoğu zaman kimliği yeniden doğrulamadan.

Kaynaklarda tartışılan neredeyse her olay, bu üçüncü adımın örtük olarak güvenilir sayılmasına dayanıyor. "Küme içi" bir güvenlik sınırı değildir.

Desen 1 — Kimlik doğrulamayı gateway'de merkezîleştir

Kaynaklardaki en güçlü mutabakat: kimlik doğrulamayı API gateway'de bir kez sonlandır ve içeriye doğrulanabilir bir kimlik taşı. Spring Cloud Gateway artı bir resource-server yapılandırması kanonik kurulumdur.

GatewaySecurityConfig.java
@Configuration
@EnableWebFluxSecurity
public class GatewaySecurityConfig {
 
  @Bean
  public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    return http
        .csrf(ServerHttpSecurity.CsrfSpec::disable)
        .authorizeExchange(ex -> ex
            .pathMatchers("/public/**").permitAll()
            .anyExchange().authenticated())
        .oauth2ResourceServer(oauth -> oauth.jwt(Customizer.withDefaults()))
        .build();
  }
}

JWT bir kez doğrulanır. Aşağı akıştaki servisler, son kullanıcıyı her adımda yeniden doğrulamak yerine gateway tarafından imzalanmış token'a güvenir.

Desen 2 — Yine de servisler arası çağrıları savun

Kimliği uçta merkezîleştirmek gereklidir ama yeterli değildir. Gerçek olaylara en çok inen kaynaklar, iç çağrılarda katmanlı savunmayı savundu. İki tamamlayıcı teknik defalarca öne çıktı:

  1. Aşağı akış servisine kapsamlanmış, kısa ömürlü, taşınan JWT'ler.
  2. Kimliğin uygulama kodundan bağımsız olarak taşıma katmanında zorlandığı, service mesh üzerinden mTLS.

Tekrar eden ders: uygulama seviyesindeki token'lar kullanıcı kim sorusunu, mesh ise hangi servis çağırıyor sorusunu yanıtlar. İkisine de cevap gerekir.

Desen 3 — Metot seviyesi yetkilendirme serviste kalır

Bir gateway ve mesh olsa bile, yetkilendirme kuralı iş mantığının yanına aittir. Spring Security'nin metot anotasyonları bu kuralı okunabilir ve test edilebilir tutar:

@Service
public class AccountService {
 
  @PreAuthorize("hasAuthority('SCOPE_account:read') and #ownerId == authentication.name")
  public Account getAccount(String ownerId) {
    return repository.findByOwner(ownerId);
  }
}

Kaynakların çeliştiği yer

Literatür hemfikir değil. En keskin ayrışma token stratejisinde:

YaklaşımÖne sürülen güçÖne sürülen zayıflık
Opak token'larKolay iptalİntrospeksiyon gecikmesi
Kendine yeten JWT'lerİntrospeksiyon turu yokİptal zordur
Yalnızca mesh kimliğiUygulama koduna şeffafKullanıcı talebi taşımaz

Evrensel bir kazanan yok — doğru cevap, iptal gereksinimlerine ve ağa ne kadar güvendiğine bağlı.

Çıkarımlar

  • Gateway'de bir kez kimlik doğrula, ama iç çağrıları asla güvenilir sayma.
  • Uygulama seviyesi token'ları (kullanıcı kimliği) mesh mTLS (servis kimliği) ile birleştir.
  • İnce taneli yetkilendirmeyi gateway'de değil, iş mantığının yanında tut.
  • Token stratejisi bir varsayılan değil, bir ödünleşmedir — bilinçli seç.

Bu, daha uzun bir içerik analizi raporunun özetidir. Tam kaynak listesi ve kodlama şeması için bana ulaş.