Spring Security - Cache Control Header

Frühjahrssicherheit - Header der Cache-Steuerung

1. Einführung

In diesem Artikel erfahren Sie, wie Sie das HTTP-Caching mit Spring Security steuern können.

Wir werden das Standardverhalten demonstrieren und auch die Gründe dafür erläutern. Wir werden dann nach Möglichkeiten suchen, dieses Verhalten teilweise oder vollständig zu ändern.

2. Standard-Caching-Verhalten

Durch die effektive Verwendung von Cache-Steuerelement-Headern können wir unseren Browser anweisen, Ressourcen zwischenzuspeichern und Netzwerk-Hops zu vermeiden. Dies verringert die Latenz und auch die Last auf unserem Server.

Standardmäßig legt Spring Security bestimmte Cache-Steuerelement-Header-Werte für uns fest, ohne dass wir etwas konfigurieren müssen.

Lassen Sie uns zunächst Spring Security für unsere Anwendung einrichten:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {}
}

Wir überschreibenconfigure(), um nichts zu tun. Dies bedeutet, dass wir nicht authentifiziert werden müssen, um einen Endpunkt zu erreichen, sodass wir uns auf das reine Testen des Caching konzentrieren können.

Als Nächstes implementieren wir einen einfachen REST-Endpunkt:

@GetMapping("/default/users/{name}")
public ResponseEntity getUserWithDefaultCaching(@PathVariable String name) {
    return ResponseEntity.ok(new UserDto(name));
}

Der resultierendecache-control-Header sieht folgendermaßen aus:

[cache-control: no-cache, no-store, max-age=0, must-revalidate]

Lassen Sie uns abschließend einen Test implementieren, der den Endpunkt erreicht, und bestätigen, welche Header in der Antwort gesendet werden:

given()
  .when()
  .get(getBaseUrl() + "/default/users/Michael")
  .then()
  .header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
  .header("Pragma", "no-cache");

Dies bedeutet im Wesentlichen, dass ein Browser diese Antwort niemals zwischenspeichert.

Obwohl dies ineffizient erscheinen mag, gibt es tatsächlich einen guten Grund für dieses Standardverhalten -If one user logs out and another one logs in, we don’t want them to be able to see the previous users resources. Es ist viel sicherer, standardmäßig nichts zwischenzuspeichern, und wir sind dafür verantwortlich, das Zwischenspeichern explizit zu aktivieren.

3. Überschreiben des Standard-Caching-Verhaltens

Manchmal haben wir es vielleicht mit Ressourcen zu tun, die zwischengespeichert werden sollen. Wenn wir es aktivieren, ist es am sichersten, es auf Ressourcenbasis zu tun. Dies bedeutet, dass alle anderen Ressourcen weiterhin standardmäßig nicht zwischengespeichert werden.

Versuchen Sie dazu, die Cache-Steuerelement-Header in einer einzelnen Handler-Methode mithilfe desCacheControl-Caches zu überschreiben. Die KlasseCacheControl ist ein fließender Builder, der es uns leicht macht, verschiedene Arten von Caching zu erstellen:

@GetMapping("/users/{name}")
public ResponseEntity getUser(@PathVariable String name) {
    return ResponseEntity.ok()
      .cacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS))
      .body(new UserDto(name));
}

Lassen Sie uns diesen Endpunkt in unserem Test erreichen und bestätigen, dass wir die Header geändert haben:

given()
  .when()
  .get(getBaseUrl() + "/users/Michael")
  .then()
  .header("Cache-Control", "max-age=60");

Wie wir sehen können, haben wir die Standardeinstellungen überschrieben. Jetzt wird unsere Antwort 60 Sekunden lang von einem Browser zwischengespeichert.

4. Deaktivieren des Standard-Caching-Verhaltens

Wir können auch die Standard-Cache-Steuerelement-Header von Spring Security insgesamt deaktivieren. Dies ist eine ziemlich riskante Sache und nicht wirklich zu empfehlen. Aber wenn wir wirklich wollen, können wir es versuchen, indem wir dieconfigure-Methode derWebSecurityConfigurerAdapter: überschreiben

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.headers().disable();
}

Lassen Sie uns nun erneut eine Anfrage an unseren Endpunkt senden und sehen, welche Antwort wir erhalten:

given()
  .when()
  .get(getBaseUrl() + "/default/users/Michael")
  .then()
  .headers(new HashMap());

Wie wir sehen können, wurden überhaupt keine Cache-Header gesetzt. Wiederumthis is not secure but proves how we can turn off the default headers if we want to.

7. Fazit

Dieser Artikel beschreibt, wie Spring Security das HTTP-Caching standardmäßig deaktiviert, und erklärt, dass dies darauf zurückzuführen ist, dass keine sicheren Ressourcen zwischengespeichert werden sollen. Wir haben auch gesehen, wie wir dieses Verhalten nach Belieben deaktivieren oder ändern können.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie inGitHub project - dies ist ein Maven-Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.