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.
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.
@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ı:
- Aşağı akış servisine kapsamlanmış, kısa ömürlü, taşınan JWT'ler.
- 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, iş 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'lar | Kolay iptal | İntrospeksiyon gecikmesi |
| Kendine yeten JWT'ler | İntrospeksiyon turu yok | İptal zordur |
| Yalnızca mesh kimliği | Uygulama koduna şeffaf | Kullanı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ş.