Il modo principale per ottenere una sessione amministrativa o un risolutore di risorse in AEM era utilizzare il SlingRepository.loginAdministrative()
e ResourceResolverFactory.getAdministrativeResourceResolver()
metodi forniti da Sling.
Tuttavia, nessuno di questi metodi è stato progettato intorno al principio del minimo privilegio e rendi troppo facile per uno sviluppatore non pianificare una struttura adeguata e i corrispondenti livelli di controllo accessi (ACL, Access Control Levels) per il loro contenuto all'inizio. Se una vulnerabilità è presente in un tale servizio, spesso porta a escalation di privilegi per admin
utente, anche se il codice stesso non avrebbe bisogno di privilegi amministrativi per funzionare.
In alcuni casi la sessione di amministrazione non viene utilizzata o la funzione viene disabilitata completamente. Se questo è il caso dell’implementazione, assicurati di rimuovere completamente la funzione o di adattarla a Codice NOP.
Ogni volta che è possibile, riFattore della funzione in modo che la sessione di richiesta autenticata specificata possa essere utilizzata per leggere o scrivere contenuti. Se ciò non è fattibile, spesso si può ottenere applicando le priorità seguenti.
Molti problemi possono essere risolti ristrutturando il contenuto. Tieni presenti queste semplici regole durante la ristrutturazione:
Modifica controllo accesso
Ottimizzare la struttura dei contenuti
Reimpostare il codice in modo che sia un servizio appropriato
Inoltre, assicurati che tutte le nuove funzioni sviluppate siano conformi ai seguenti principi:
I requisiti di sicurezza devono guidare la struttura del contenuto
Utilizzare nodetypes
Rispetta le impostazioni della privacy
/profile
nodo.Che si applichi il controllo degli accessi durante la ristrutturazione del contenuto o quando lo si fa per un nuovo utente di servizio, è necessario applicare gli ACL più rigidi possibile. Utilizzare tutte le possibilità di controllo dell'accesso:
Ad esempio, anziché applicare jcr:read
su /apps
, applica solo a /apps/*/components/*/analytics
Utilizzo restrizioni
Applica ACL per i tipi di nodo
Autorizzazioni limite
jcr:write
autorizzazione; use jcr:modifyProperties
anzichéSe quanto sopra non riesce, Sling 7 offre un servizio di mappatura utenti del servizio che consente di configurare una mappatura bundle-to-user e due metodi API corrispondenti: [SlingRepository.loginService()](https://sling.apache.org/apidocs/sling7/org/apache/sling/jcr/api/SlingRepository.html#loginService-java.lang.String-java.lang.String-)
e [ResourceResolverFactory.getServiceResourceResolver()](https://sling.apache.org/apidocs/sling7/org/apache/sling/api/resource/ResourceResolverFactory.html#getServiceResourceResolver-java.util.Map-)
che restituisce un risolutore di sessione/risorse con i privilegi di un solo utente configurato. Questi metodi hanno le seguenti caratteristiche:
Consentono di mappare i servizi agli utenti
Consentono di definire gli utenti dei servizi secondari
Il punto di configurazione centrale è: org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl
service-id
= service-name
[ ":" nome-servizio secondario ]
service-id
è mappato a un risolutore di risorse e/o a un ID utente dell’archivio JCR per l’autenticazione
service-name
è il nome simbolico del bundle che fornisce il servizio
Un utente di servizio è un utente JCR senza password impostata e con un set minimo di privilegi necessari per eseguire un'attività specifica. Se non è impostata alcuna password, non sarà possibile accedere con un utente del servizio.
Un modo per rendere obsoleta una sessione amministrativa consiste nel sostituirla con sessioni utente di servizio. Se necessario, potrebbe anche essere sostituito da più utenti di servizi secondari.
Per sostituire la sessione di amministrazione con un utente di servizio, esegui i seguenti passaggi:
Identifica le autorizzazioni necessarie per il tuo servizio, tenendo presente il principio della minima autorizzazione.
Controlla se c'è già un utente disponibile con esattamente la configurazione dell'autorizzazione necessaria. Crea un nuovo utente del servizio di sistema se nessun utente esistente soddisfa le tue esigenze. RTC è necessario per creare un nuovo utente di servizio. A volte ha senso creare più utenti di servizi secondari (ad esempio, uno per la scrittura e uno per la lettura) per compartimentare l'accesso ancora di più.
Imposta e verifica gli ACE per l’utente.
Aggiungi un service-user
mappatura per il servizio e per user/sub-users
Rendi la funzione sling dell'utente del servizio disponibile per il tuo bundle: aggiornamento alla versione più recente di org.apache.sling.api
.
Sostituisci il admin-session
nel tuo codice con loginService
o getServiceResourceResolver
API.
Dopo aver verificato che nessun utente nell’elenco degli utenti del servizio AEM è applicabile al tuo caso d’uso e che i corrispondenti problemi RTC sono stati approvati, puoi procedere e aggiungere il nuovo utente al contenuto predefinito.
L'approccio consigliato è quello di creare un utente di servizio per utilizzare l'esploratore del repository in https://<server>:<port>/crx/explorer/index.jsp
L'obiettivo è quello di ottenere una jcr:uuid
che è obbligatorio per creare l'utente tramite un'installazione di un pacchetto di contenuti.
Puoi creare utenti del servizio:
Andando al repository explorer all'indirizzo https://<server>:<port>/crx/explorer/index.jsp
Accedere come amministratore premendo il pulsante Accesso nell’angolo in alto a sinistra dello schermo.
Quindi, crea e denomina l'utente di sistema. Per creare l'utente come un sistema, impostare il percorso intermedio come system
e aggiungi sottocartelle facoltative in base alle tue esigenze:
Verifica che il nodo utente del sistema si presenti come segue:
Non esistono tipi di mixin associati agli utenti del servizio. Ciò significa che non vi saranno criteri di controllo degli accessi per gli utenti del sistema.
Quando aggiungi il corrispondente .content.xml al contenuto del bundle, assicurati di aver impostato il rep:authorizableId
e che il tipo principale è rep:SystemUser
. Dovrebbe essere così:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:rep="internal"
jcr:primaryType="rep:SystemUser"
jcr:uuid="4917dd68-a0c1-3021-b5b7-435d0044b0dd"
rep:principalName="authentication-service"
rep:authorizableId="authentication-service"/>
Per aggiungere una mappatura dal servizio agli utenti di sistema corrispondenti, è necessario creare una configurazione di fabbrica per [ServiceUserMapper](https://sling.apache.org/apidocs/sling7/org/apache/sling/serviceusermapping/ServiceUserMapper.html)
servizio. Per mantenere questa modulare tali configurazioni possono essere fornite utilizzando Meccanismo di modifica dello Sling. Il modo consigliato per installare tali configurazioni con il tuo bundle è quello di utilizzare Caricamento del contenuto iniziale di Sling:
Crea una sottocartella SLING-INF/content sotto la cartella src/main/resources del bundle
In questa cartella crea un file chiamato org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.modified-<some unique="" name="" for="" your="" factory="" configuration="">.xml con il contenuto della configurazione di fabbrica (incluse tutte le mappature utente dei servizi secondari). Esempio:
Crea un SLING-INF/content
sotto la cartella src/main/resources
cartella del tuo bundle;
In questa cartella crea un file named org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-<a unique name for your factory configuration>.xml
con il contenuto della configurazione di fabbrica, incluse tutte le mappature utente dei servizi secondari.
A scopo illustrativo, utilizza un file denominato org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-com.adobe.granite.auth.saml.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<node>
<primaryNodeType>sling:OsgiConfig</primaryNodeType>
<property>
<name>user.default</name>
<value></value>
</property>
<property>
<name>user.mapping</name>
<values>
<value>com.adobe.granite.auth.saml=authentication-service</value>
</values>
</property>
</node>
Fai riferimento al contenuto iniziale Sling nella configurazione del maven-bundle-plugin
in pom.xml
del tuo bundle. Esempio:
<Sling-Initial-Content>
SLING-INF/content;path:=/libs/system/config;overwrite:=true;
</Sling-Initial-Content>
Installa il bundle e assicurati che la configurazione di fabbrica sia stata installata. Per farlo, segui questi passaggi:
Chiamate a loginAdministrative()
vengono spesso visualizzati insieme a sessioni condivise. Queste sessioni vengono acquisite all’attivazione del servizio e vengono disconnesse solo dopo l’arresto del servizio. Anche se questa è una pratica comune, porta a due problemi:
La soluzione più ovvia per il rischio di sicurezza è semplicemente sostituire il loginAdministrative()
chiama con un loginService()
uno per un utente con privilegi limitati. Tuttavia, questo non avrà alcun impatto su eventuali potenziali degrado delle prestazioni. Una possibilità di mitigare questo problema è quella di racchiudere tutte le informazioni richieste in un oggetto che non ha alcuna associazione con la sessione. Quindi, crea (o distruggi) la sessione su richiesta.
L’approccio consigliato consiste nel refactorizzare l’API del servizio per dare al chiamante il controllo sulla creazione/distruzione della sessione.
JSP non può utilizzare loginService()
, perché non è presente alcun servizio associato. Tuttavia, le sessioni amministrative in JSP sono solitamente un segno di una violazione del paradigma MVC.
Questo può essere corretto in due modi:
Il primo metodo è quello preferito.
Quando si elaborano eventi o lavori e, in alcuni casi, flussi di lavoro, la sessione corrispondente che ha attivato l’evento viene in genere persa. Questo porta a gestori di eventi e processori di processi che utilizzano spesso sessioni amministrative per svolgere il loro lavoro. Ci sono diversi approcci concepibili per risolvere questo problema, ciascuno con i loro vantaggi e svantaggi:
Passa la user-id
nel payload dell’evento e utilizza la rappresentazione.
Vantaggi: Facile da usare.
Svantaggi: Usi fissi loginAdministrative()
. autentica nuovamente una richiesta già autenticata.
Crea o riutilizza un utente del servizio che ha accesso ai dati.
Vantaggi: Coerente con la progettazione corrente. Ha bisogno di un cambiamento minimo.
Svantaggi: Ha bisogno di utenti di servizi molto potenti per essere flessibili, che può facilmente portare a escalation di privilegi. Attiva il modello di sicurezza.
Passa una serializzazione del Subject
nel payload dell’evento e crea un ResourceResolver
in base a tale argomento. Un esempio potrebbe essere l'utilizzo di JAAS doAsPrivileged
in ResourceResolverFactory
.
Vantaggi: Pulisci l'implementazione dal punto di vista della sicurezza. Evita la riautenticazione e funziona con i privilegi originali. Il codice relativo alla sicurezza è trasparente per il consumatore dell'evento.
Svantaggi: Ha bisogno di essere refactoring. Anche il fatto che il codice relativo alla sicurezza sia trasparente per il consumatore dell'evento potrebbe causare problemi.
Il terzo approccio è attualmente la tecnica di elaborazione preferita.
Nelle implementazioni del processo del flusso di lavoro, la sessione utente corrispondente che ha attivato il flusso di lavoro in genere viene persa. Questo porta ai processi del flusso di lavoro che utilizzano spesso sessioni amministrative per eseguire il loro lavoro.
Per risolvere questi problemi, si raccomanda che gli stessi approcci indicati in Eventi di elaborazione, preprocessori di replica e processi da utilizzare.
Ci sono un paio di sessioni amministrative utilizzate nelle implementazioni di processori sling POST. Di solito, le sessioni amministrative vengono utilizzate per accedere ai nodi in attesa di eliminazione all’interno di POST in fase di elaborazione. Di conseguenza, non sono più disponibili tramite la sessione di richiesta. È possibile accedere a un nodo in attesa di eliminazione per rivelare un metada che altrimenti non dovrebbe essere accessibile.