Caching di contenuto protetto

Il caching sensibile alle autorizzazioni consente di memorizzare nella cache le pagine protette. Il dispatcher controlla le autorizzazioni di accesso dell'utente per una pagina prima di distribuirla nella cache.

Dispatcher include il modulo AuthChecker che implementa il caching sensibile alle autorizzazioni. Quando il modulo è attivato, il rendering chiama un servlet AEM per eseguire l'autenticazione utente e l'autorizzazione per il contenuto richiesto. La risposta del servlet determina se il contenuto viene inviato al browser Web.

Poiché i metodi di autenticazione e autorizzazione sono specifici per la distribuzione AEM, è necessario creare il servlet.

NOTA

Utilizzate i filtri deny per applicare restrizioni di protezione predefinite. Utilizzate il caching sensibile alle autorizzazioni per le pagine configurate per consentire l'accesso a un sottoinsieme di utenti o gruppi.

I diagrammi seguenti illustrano l'ordine degli eventi che si verificano quando un browser Web richiede una pagina per la quale viene utilizzato il caching sensibile alle autorizzazioni.

La pagina è memorizzata nella cache e l'utente è autorizzato

  1. Il dispatcher determina che il contenuto richiesto è memorizzato nella cache e valido.
  2. Il dispatcher invia un messaggio di richiesta al rendering. La sezione HEAD include tutte le righe di intestazione della richiesta del browser.
  3. Il rendering chiama l’autore per eseguire il controllo di sicurezza e risponde al dispatcher. Il messaggio di risposta include un codice di stato HTTP pari a 200 per indicare che l'utente è autorizzato.
  4. Il dispatcher invia un messaggio di risposta al browser composto dalle righe di intestazione della risposta di rendering e dal contenuto memorizzato nella cache del corpo.

La pagina non è memorizzata nella cache e l'utente è autorizzato

  1. Il dispatcher determina che il contenuto non è memorizzato nella cache o richiede un aggiornamento.
  2. Il dispatcher inoltra la richiesta originale al rendering.
  3. Il rendering chiama il servlet dell’autore per eseguire un controllo di sicurezza. Quando l’utente è autorizzato, il rendering include la pagina di cui è stato effettuato il rendering nel corpo del messaggio di risposta.
  4. Il dispatcher inoltra la risposta al browser. Dispatcher aggiunge il corpo del messaggio di risposta del rendering alla cache.

Utente non autorizzato

  1. Il dispatcher controlla la cache.
  2. Il dispatcher invia al rendering un messaggio di richiesta che include tutte le righe di intestazione della richiesta del browser.
  3. Il rendering chiama il servlet dell’autore per eseguire un controllo di sicurezza che non riesce e il rendering inoltra la richiesta originale al dispatcher.

Implementazione del caching sensibile alle autorizzazioni

Per implementare il caching sensibile alle autorizzazioni, effettuate le seguenti operazioni:

  • Sviluppare un servlet che esegue l'autenticazione e l'autorizzazione
  • Configurare il dispatcher
NOTA

In genere, le risorse protette vengono memorizzate in una cartella separata rispetto ai file non protetti. Ad esempio, /content/secure/

Creare il servlet di autorizzazione

Creare e distribuire un servlet che esegue l'autenticazione e l'autorizzazione dell'utente che richiede il contenuto Web. Il servlet può utilizzare qualsiasi metodo di autenticazione e autorizzazione, ad esempio l'account utente AEM e gli ACL dell'archivio oppure un servizio di ricerca LDAP. Distribuite il servlet nell'istanza AEM utilizzata da Dispatcher come rendering.

Il servlet deve essere accessibile a tutti gli utenti. Pertanto, il servlet deve estendere la classe org.apache.sling.api.servlets.SlingSafeMethodsServlet, che fornisce l'accesso in sola lettura al sistema.

Il servlet riceve solo le richieste HEAD dal rendering, pertanto è necessario implementare solo il metodo doHead.

Il rendering include l’URI della risorsa richiesta come parametro della richiesta HTTP. Ad esempio, un servlet di autorizzazione è accessibile tramite /bin/permissioncheck. Per eseguire un controllo di sicurezza nella pagina /content/geometrixx-outdoors/en.html, il rendering include il seguente URL nella richiesta HTTP:

/bin/permissioncheck?uri=/content/geometrixx-outdoors/en.html

Il messaggio di risposta del servlet deve contenere i seguenti codici di stato HTTP:

  • 200: Autenticazione e autorizzazione passate.

Il servlet di esempio seguente ottiene l’URL della risorsa richiesta dalla richiesta HTTP. Il codice utilizza l'annotazione Felix SCR Property per impostare il valore della proprietà sling.servlet.paths su /bin/permissioncheck. Nel metodo doHead, il servlet ottiene l'oggetto session e utilizza il metodo checkPermission per determinare il codice di risposta appropriato.

NOTA

Il valore della proprietà sling.servlet.paths deve essere attivato nel servizio Sling Servlet Resolver (org.apache.sling.servlets.resolver.SlingServletResolver).

Esempio di servlet

package com.adobe.example;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Property;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Session;

@Component(metatype=false)
@Service
public class AuthcheckerServlet extends SlingSafeMethodsServlet {
 
    @Property(value="/bin/permissioncheck")
    static final String SERVLET_PATH="sling.servlet.paths";
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    public void doHead(SlingHttpServletRequest request, SlingHttpServletResponse response) {
     try{ 
      //retrieve the requested URL
      String uri = request.getParameter("uri");
      //obtain the session from the request
      Session session = request.getResourceResolver().adaptTo(javax.jcr.Session.class);     
      //perform the permissions check
      try {
       session.checkPermission(uri, Session.ACTION_READ);
       logger.info("authchecker says OK");
       response.setStatus(SlingHttpServletResponse.SC_OK);
      } catch(Exception e) {
       logger.info("authchecker says READ access DENIED!");
       response.setStatus(SlingHttpServletResponse.SC_FORBIDDEN);
      }
     }catch(Exception e){
      logger.error("authchecker servlet exception: " + e.getMessage());
     }
    }
}

Configurare il dispatcher per il caching sensibile alle autorizzazioni

La sezione auth_checker del file dispatcher.any controlla il funzionamento del caching sensibile alle autorizzazioni. La sezione auth_checker include le seguenti sottosezioni:

  • url: Il valore della sling.servlet.paths proprietà del servlet che esegue il controllo di sicurezza.

  • filter: Filtri che specificano le cartelle a cui viene applicato il caching sensibile alle autorizzazioni. In genere, un filtro deny viene applicato a tutte le cartelle e i filtri allow vengono applicati alle cartelle protette.

  • headers: Specifica le intestazioni HTTP incluse nel servlet di autorizzazione nella risposta.

All'avvio del dispatcher, il file di registro del dispatcher include il seguente messaggio a livello di debug:

AuthChecker: initialized with URL 'configured_url'.

La sezione auth_checker di esempio seguente configura Dispatcher per l’utilizzo del servlet dell’argomento precedente. La sezione del filtro determina l'esecuzione dei controlli delle autorizzazioni solo per le risorse HTML protette.

Configurazione esempio

/auth_checker
  {
  # request is sent to this URL with '?uri=<page>' appended
  /url "/bin/permissioncheck"
      
  # only the requested pages matching the filter section below are checked,
  # all other pages get delivered unchecked
  /filter
    {
    /0000
      {
      /glob "*"
      /type "deny"
      }
    /0001
      {
      /glob "/content/secure/*.html"
      /type "allow"
      }
    }
  # any header line returned from the auth_checker's HEAD request matching
  # the section below will be returned as well
  /headers
    {
    /0000
      {
      /glob "*"
      /type "deny"
      }
    /0001
      {
      /glob "Set-Cookie:*"
      /type "allow"
      }
    }
  }

In questa pagina