Cache-Control in Spring Boot
Spring Security setzt no-cache, no-store automatisch -- passen Sie die Defaults an für statische Assets, API-Responses und sensible Daten.
Cache-Control in Spring Boot
Cache-Control steuert, wie Browser und Proxies Responses cachen. Für sensible Daten ist no-store zwingend, für statische Assets ist aggressives Caching mit immutable optimal. Der Header ist mit 8 von 166 Punkten im Wolf-Agents Web Security Check bewertet.
Spring Security setzt Cache-Control: no-cache, no-store, max-age=0, must-revalidate automatisch für alle geschützten Responses. Das ist sicher, aber für statische Assets zu restriktiv. Sie müssen die Cache-Strategie differenziert anpassen: no-store für sensible Daten, immutable für fingerprinted Assets.
Spring Security Cache-Defaults verstehen
Spring Security setzt für alle Responses, die durch die SecurityFilterChain laufen, automatisch Cache-Control: no-cache, no-store, max-age=0, must-revalidate. Das verhindert, dass sensible Seiten im Browser-Cache landen. Für statische Assets ist das jedoch zu restriktiv.
// Spring Security setzt automatisch:
// Cache-Control: no-cache, no-store, max-age=0, must-revalidate
// Pragma: no-cache
// Expires: 0
// SecurityConfig.java -- Cache-Control anpassen
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
http.headers(headers -> headers
// Spring Security Cache-Control deaktivieren
// (nur wenn Sie eigene Cache-Strategie haben!)
.cacheControl(cache -> cache.disable())
);
return http.build();
}Deaktivieren Sie Spring Securitys cacheControl nur, wenn Sie eine eigene differenzierte Cache-Strategie implementieren. Ohne Cache-Control landen sensible Daten im Browser-Cache.
Statische Ressourcen cachen
Konfigurieren Sie aggressives Caching für statische Assets über den ResourceHandler. Fingerprinted Assets (mit Content-Hash im Dateinamen) können immutable und max-age=365d verwenden. Bilder und Fonts brauchen angepasste Cache-Zeiten.
// WebConfig.java -- Cache fuer statische Ressourcen
@Configuration
public class WebConfig
implements WebMvcConfigurer {
@Override
public void addResourceHandlers(
ResourceHandlerRegistry registry) {
// Fingerprinted Assets (JS, CSS mit Hash)
registry.addResourceHandler("/assets/**")
.addResourceLocations("classpath:/static/assets/")
.setCacheControl(CacheControl
.maxAge(Duration.ofDays(365))
.cachePublic()
.immutable());
// Bilder (lange, aber nicht immutable)
registry.addResourceHandler("/images/**")
.addResourceLocations("classpath:/static/images/")
.setCacheControl(CacheControl
.maxAge(Duration.ofDays(30))
.cachePublic());
// Fonts
registry.addResourceHandler("/fonts/**")
.addResourceLocations("classpath:/static/fonts/")
.setCacheControl(CacheControl
.maxAge(Duration.ofDays(365))
.cachePublic()
.immutable());
}
}Differenzierte Cache-Strategie
Verwenden Sie in REST-Controllern ResponseEntity mit individuellen CacheControl-Werten. Öffentliche API-Daten können kurz gecacht werden, sensible Nutzerdaten müssen no-store verwenden.
// Controller mit individueller Cache-Strategie
@RestController
public class ApiController {
// Oeffentliche API -- kurzer Cache
@GetMapping("/api/public/data")
public ResponseEntity<Data> publicData() {
return ResponseEntity.ok()
.cacheControl(CacheControl
.maxAge(Duration.ofMinutes(5))
.cachePublic())
.body(loadData());
}
// Private API -- kein Cache
@GetMapping("/api/user/profile")
public ResponseEntity<Profile> userProfile() {
return ResponseEntity.ok()
.cacheControl(CacheControl.noStore())
.body(loadProfile());
}
}Cache-Control verifizieren
Prüfen Sie die Cache-Control-Header für verschiedene Ressourcentypen. Statische Assets sollten public, max-age=31536000, immutable haben, sensible API-Endpoints no-store.
# Cache-Control pruefen
curl -sI http://localhost:8080/assets/app.a1b2c3.js | \
grep -i cache-control
# Erwartete Ausgabe (statische Assets):
cache-control: public, max-age=31536000, immutable
# API-Endpoint pruefen:
curl -sI http://localhost:8080/api/user/profile | \
grep -i cache-control
# Erwartete Ausgabe (sensible Daten):
cache-control: no-storeHäufige Fehler bei Cache-Control in Spring Boot
Spring Security Cache-Control pauschal deaktiviert
Wer cacheControl().disable() setzt ohne eigene Strategie, entfernt den Cache-Schutz für alle Responses -- auch für Seiten mit sensiblen Daten wie Dashboards und Profil-Seiten.
Statische Assets per web.ignoring() ausgeschlossen
Mit web.ignoring() fehlen nicht nur Cache-Control, sondern alle Security-Header. Verwenden Sie permitAll() und den ResourceHandler für statische Assets.
Actuator-Endpoints cachen sensible Daten
Actuator-Endpoints wie /actuator/env oder /actuator/health können sensible Informationen enthalten. Stellen Sie sicher, dass diese Endpoints no-store verwenden.
immutable ohne Content-Hash im Dateinamen
Das immutable-Attribut sagt dem Browser, die Datei nie zu revalidieren. Ohne Content-Hash im Dateinamen können Aenderungen nicht ausgeliefert werden. Verwenden Sie Webpack oder Vite Content-Hashing.
Compliance-Relevanz
Korrektes Cache-Control ist essentiell für den Schutz sensibler Daten und wird von mehreren Compliance-Frameworks gefordert.
Wie steht Ihre Domain bei Cache-Control?
Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.