Spring Security - Intestazioni di controllo della cache

1. Introduzione

In questo articolo, esploreremo come controllare la cache HTTP con Spring Security.

Dimostreremo il suo comportamento predefinito e spiegheremo anche il ragionamento alla base. Vedremo quindi come modificare questo comportamento, parzialmente o completamente.

2. Comportamento di memorizzazione nella cache predefinito

Utilizzando efficacemente le intestazioni di controllo della cache, possiamo istruire il nostro browser a memorizzare nella cache le risorse ed evitare salti di rete. Ciò riduce la latenza e anche il carico sul nostro server.

Per impostazione predefinita, Spring Security imposta valori di intestazione di controllo della cache specifici per noi, senza che dobbiamo configurare nulla.

Innanzitutto, configuriamo Spring Security per la nostra applicazione:

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception {} }

Stiamo sovrascrivendo configure () per non fare nulla, questo significa che non avremo bisogno di essere autenticati per raggiungere un endpoint, permettendoci di concentrarci esclusivamente sul test del caching.

Successivamente, implementiamo un semplice endpoint REST:

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

L' intestazione di controllo della cache risultante sarà simile a questa:

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

Infine, implementiamo un test che raggiunga l'endpoint e affermiamo quali intestazioni vengono inviate nella risposta:

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

In sostanza, ciò significa che un browser non memorizzerà mai questa risposta nella cache.

Anche se questo può sembrare inefficiente, in realtà c'è una buona ragione per questo comportamento predefinito: se un utente si disconnette e un altro accede, non vogliamo che sia in grado di vedere le risorse degli utenti precedenti . È molto più sicuro non memorizzare nella cache nulla per impostazione predefinita e lasciare a noi la responsabilità di abilitare esplicitamente la cache.

3. Ignorare il comportamento di memorizzazione nella cache predefinito

A volte potremmo avere a che fare con risorse che vogliamo che siano memorizzate nella cache. Se vogliamo abilitarlo, sarebbe più sicuro farlo in base alle risorse. Ciò significa che tutte le altre risorse non verranno comunque memorizzate nella cache per impostazione predefinita.

Per fare ciò, proviamo a sovrascrivere le intestazioni di controllo della cache in un unico metodo del gestore, utilizzando la cache CacheControl . La classe CacheControl è un builder fluente, che ci rende facile creare diversi tipi di caching:

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

Raggiungiamo questo endpoint nel nostro test e affermiamo di aver modificato le intestazioni:

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

Come possiamo vedere, abbiamo sovrascritto le impostazioni predefinite e ora la nostra risposta verrà memorizzata nella cache da un browser per 60 secondi.

4. Disattivazione del comportamento di memorizzazione nella cache predefinito

Possiamo anche disattivare del tutto le intestazioni di controllo della cache predefinite di Spring Security. Questa è una cosa piuttosto rischiosa da fare e non è davvero consigliata. Ma se lo vogliamo davvero, possiamo provarlo sovrascrivendo il metodo configure di WebSecurityConfigurerAdapter:

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

Ora, facciamo di nuovo una richiesta al nostro endpoint e vediamo quale risposta otteniamo:

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

Come possiamo vedere, non è stata impostata alcuna intestazione della cache. Di nuovo, questo non è sicuro, ma dimostra come possiamo disattivare le intestazioni predefinite se lo vogliamo.

5. conclusione

Questo articolo dimostra come Spring Security disabiliti la cache HTTP per impostazione predefinita e spiega che ciò è dovuto al fatto che non vogliamo memorizzare nella cache le risorse protette. Abbiamo anche visto come possiamo disabilitare o modificare questo comportamento come riteniamo opportuno.

L'implementazione di tutti questi esempi e frammenti di codice può essere trovata nel progetto GitHub: questo è un progetto Maven, quindi dovrebbe essere facile da importare ed eseguire così com'è.