Il modo principale per ottenere una sessione amministrativa o un risolutore di risorse in AEM era utilizzare i metodi SlingRepository.loginAdministrative()
e ResourceResolverFactory.getAdministrativeResourceResolver()
forniti da Sling.
Tuttavia, nessuno di questi metodi è stato progettato intorno al principio del privilegio minimo e rende troppo facile per uno sviluppatore non pianificare una struttura adeguata e i corrispondenti livelli di controllo accessi (ACL) per il loro contenuto all'inizio. Se una vulnerabilità è presente in un tale servizio, spesso porta a privilegiare le escalation all'utente admin
, 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 con 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
.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, invece di applicare jcr:read
su /apps
, applicalo solo a /apps/*/components/*/analytics
Usa restrizioni
Applica ACL per i tipi di nodo
Autorizzazioni limite
jcr:write
; utilizza invece jcr:modifyProperties
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-)
restituiscono 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 una mappatura service-user
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 admin-session
nel codice con le API loginService
o getServiceResourceResolver
.
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 all'indirizzo https://<server>:<port>/crx/explorer/index.jsp
L'obiettivo è quello di ottenere una proprietà jcr:uuid
valida che è obbligatoria per creare l'utente tramite un'installazione di un pacchetto di contenuti.
Puoi creare utenti del servizio:
Andando alla directory principale archivio all'indirizzo https://<server>:<port>/crx/explorer/index.jsp
Per accedere come amministratore, premi il collegamento Accedi nell’angolo in alto a sinistra dello schermo.
Quindi, crea e denomina l'utente di sistema. Per creare l'utente come un sistema, imposta 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 sia 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 il servizio [ServiceUserMapper](https://sling.apache.org/apidocs/sling7/org/apache/sling/serviceusermapping/ServiceUserMapper.html)
. Per mantenere questo modulare tali configurazioni possono essere fornite utilizzando il meccanismo di modifica Sling. Il modo consigliato per installare tali configurazioni con il tuo bundle è quello di utilizzare Sling Initial Content Loading:
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-<qualche nome univoco per la configurazione di fabbrica>.xml con il contenuto della configurazione di fabbrica (inclusi tutti i mapping utente di servizi secondari). Esempio:
Crea una cartella SLING-INF/content
sotto la cartella src/main/resources
del 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 di maven-bundle-plugin
nel 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. Puoi eseguire questa operazione:
Le chiamate a loginAdministrative()
vengono spesso visualizzate 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 la chiamata loginAdministrative()
con una loginService()
a 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.
I JSP non possono 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 il user-id
nel payload dell’evento e utilizza la rappresentazione.
Vantaggi: Facile da usare.
Svantaggi: utilizza ancora loginAdministrative()
. autentica nuovamente una richiesta già autenticata.
Crea o riutilizza un utente del servizio che ha accesso ai dati.
Vantaggi: coerente con il design attuale. Ha bisogno di un cambiamento minimo.
Svantaggi: ha bisogno di utenti di servizi molto potenti per essere flessibili, che possono 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 soggetto. Un esempio potrebbe essere l'utilizzo del JAAS doAsPrivileged
nel ResourceResolverFactory
.
Vantaggi: pulizia dell'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: richiede il 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 consiglia di utilizzare gli stessi approcci indicati in Eventi di elaborazione, preprocessori di replica e processi.
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.