Fermer

novembre 1, 2021

Fonctionnalité AEM – Servlet de prévisualisation de l'auteur


Pourquoi est-ce nécessaire ?

Ce n'est peut-être que moi, mais j'ai trouvé incroyablement courant que les clients demandent une URL non authentifiée pour afficher les pages en cours dans une instance AEM Author. La demande a beaucoup de sens, car souvent ceux qui approuvent le contenu voudront souvent juste jeter un coup d'œil rapide, et n'ont pas besoin de beaucoup de temps dans le système AEM Author ou d'une connexion/compte dédié. Au lieu de cela, ce serait formidable d'avoir un moyen de prévisualiser le contenu avant la mise en ligne, potentiellement via un processus d'approbation hors ligne ou par e-mail. Aujourd'hui, cela n'est pas disponible immédiatement avec AEM, et les personnes qui souhaitent avoir ce comportement ont soit une instance de publication « Aperçu » dédiée, soit elles doivent mordre la balle et forcer tous leurs approbateurs à se connecter avant de voir tout contenu.

Un nouveau challenger approche

Entrez dans le servlet de prévisualisation. Ce servlet personnalisé contourne l'authentification et permet à une page de s'afficher directement sur l'instance d'auteur active. Comment, demandez-vous ? Une petite astuce dans la spécification Sling Servlet pour supprimer l'authentification sur la demande de servlet, couplée à une configuration Apache VHost distincte utilisée pour forcer tout le trafic demandé à passer par notre servlet de prévisualisation. (Idéalement, cela se fait via un sous-domaine distinct et spécifique)

Maintenant, décomposons le fonctionnement de cette servlet.

Le servlet de prévisualisation

Le servlet lui-même est assez simple. Cette servlet écoutera sur un point de terminaison donné et, à partir du suffixe transmis, déterminera le contenu à restituer. Par exemple, en utilisant notre point de terminaison par défaut, preview.html, nous pourrions afficher la page racine we-retail avec les éléments suivants :

/preview.html/content/we-retail/us/en/men.html

Le ci-dessus semblera très familier à ceux qui travaillent dans l'interface utilisateur de l'auteur AEM, car il exploite le même concept d'utilisation des suffixes. Semblable à l'interface utilisateur de création, nous utilisons le suffixe pour déterminer la page qui est référencée. Cependant, il existe une différence clé, en ce que les services prêts à l'emploi utilisant les suffixes utilisent la session/authentification initiale des utilisateurs, alors que nous devrons mettre notre service à la disposition des utilisateurs non authentifiés.

Heureusement pour nous, il existe une propriété sling pour supprimer les exigences d'authentification sur une servlet exposée. La propriété est définie comme suit :

sling.auth.requirement=-/preview

Bien sûr, en règle générale, vous souhaiterez probablement utiliser une variable statique pour définir cela au lieu d'une chaîne codée en dur, la définition ressemblera donc à ceci :

@Component(

service = {Servlet.class, Filter.class},

immédiat = vrai,

propriété = {

Constantes.SERVICE_DESCRIPTION + "=" + "Aperçu du servlet",

ServletResolverConstants.SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,

ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES + "=" + "perficient/servlet/preview",

ServletResolverConstants.SLING_SERVLET_EXTENSIONS + "=" + PreviewServlet.URL_SUFFIX,

AuthConstants.AUTH_REQUIREMENTS + "=-" + PreviewServlet.URL_PREFIX

})

Super ! Nous avons maintenant une servlet qui permet un accès non authentifié et peut lire dans le chemin de la page que nous voulons rendre ! Cependant, nous ne faisons toujours rien avec le chemin lui-même. Maintenant, les trucs amusants – Il est temps d'obtenir le contenu de la page. Pour ce faire, nous pouvons utiliser une autre classe pratique, le RequestDispatcher. Cela prendra un nœud de ressource fourni et enverra la demande de rendu. D'accord, c'est super ! Cependant, nous sommes toujours dans un état non authentifié, donc à ce stade, nous devons nous assurer de rendre le contenu comme si l'utilisateur a réellement des autorisations de lecture. C'est la partie où votre équipe de sécurité s'énerve, et je dois donner l'avertissement suivant :

Si vous ouvrez votre site d'auteur à des lecteurs anonymes, même s'il n'y a qu'un accès en lecture, vous devez être TRÈS attention aux chemins que vous exposez. Et en tant que tel, veuillez être très, très prudent dans l'attribution des autorisations d'utilisateur de votre service. demander le répartiteur. Pour ce faire, nous utilisons une stratégie relativement courante consistant à créer un wrapper de demande d'élingue et à mettre à jour ce wrapper pour qu'un utilisateur de service préconfiguré soit défini sur le résolveur de ressources. Ledit utilisateur de service dans notre implémentation est configurable via une propriété dans un /conf. Bien qu'elle ne soit pas obligatoire, il s'agit d'une méthode que je recommande vivement, en particulier pour les systèmes multi-locataires.

Voici un exemple du wrapper de servlet et de la logique de pièce jointe de l'utilisateur de service ici :

ResourceResolver resourceResolver = repoService.getResourceResolver(serviceUser );

Objet oldRR = request.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);

Mode WCMMode = WCMMode.DISABLED.toRequest(request);

essayer {

request.setAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER, resourceResolver);

Emballage SlingHttpServletRequestWrapper =

nouveau SlingHttpServletRequestWrapper (demande) {

@Passer outre

public ResourceResolver getResourceResolver() {

return resourceResolver;

}

} ;

Répartiteur RequestDispatcher = request.getRequestDispatcher(newResource);

dispatcher.forward(wrapper, réponse);
...

Notez également que nous désactivons le mode WCM – cela garantit que tout sera rendu comme s'il s'agissait d'un éditeur.

Il est temps de tester, n'est-ce pas ? Malheureusement, il nous manque ici une pièce essentielle du puzzle.

Qu'en est-il des assets et des liens internes référencés sur le contenu de la page ?!

Lorsque vous effectuez une demande via le point de terminaison du servlet ( /preview.html aux fins de cet article), les liens, ainsi que les actifs associés, seront toujours sans préfixe et nécessiteront donc une authentification pour être affichés sur l'auteur. Comment pouvons-nous contourner cela?! Eh bien, comme la plupart des problèmes de développement, il existe plusieurs façons de résoudre ce problème. Une possibilité est d'écrire un réécrivain de lien pour réécrire tout à résoudre via la servlet, en fonction du préfixe de la servlet. Cette méthode, bien que possible, est difficile et capricieuse. Au lieu de cela, une autre option pour créer un VHost séparé dans Apache dédié aux demandes de prévisualisation. Cette méthode présente quelques avantages par rapport au rewriter :

  1. Lorsque vous attribuez au servlet de prévisualisation un domaine dédié, nous pouvons très facilement ajuster l'url de passthrough pour toujours inclure /preview.html et faire en sorte que le lien exposé corresponde à vos serveurs de production[19659028]Pas besoin de maintenir deux pipelines de réécriture distincts pour le même contenu

Le VHost Apache

À ce stade, nous sommes vraiment sur le point d'avoir la solution de prévisualisation dont nous avons besoin : le balisage d'une seule page peut être consulté sans authentification. Nous devons juste nous assurer que chaque requête passe par notre servlet non authentifiée, au lieu de simplement la requête de page initiale. Bien que cela semble compliqué, c'est en fait la partie facile ! Il ne reste plus qu'à créer un VHost apache dédié à votre point de terminaison de prévisualisation. Bien que possible sans sous-domaine, c'est fortement recommandé ici – un exemple :

http://preview-author.perficient.com/

Maintenant, avec un seul mappage, nous pouvons facilement forcer tout le trafic via notre servlet ![19659035]Réécrivez /(.*) /preview.html/(.*) [PT,L]

Et puis, juste au cas où, je suggère également FORTEMENT de bloquer certains des liens AEM de base :

#301 interfaces aem au site/à l'actif qu'ils recherchent
RewriteCond ^/(sites|éditeur|actifs).html
Réécrire /.+.html/(.*) /preview.html/$1 [R=301,NC,L]

#404 système seulement points de terminaison
RewriteCond ^/(aem|crx|system)
Réécrire .* - [R=404,L]

#Aperçu de la transmission du trafic
Réécrivez /(.*) /preview.html/(.*) [PT,L]

Bien sûr, ce qui précède est à titre d'exemple uniquement – il y a et il y aura plus de chemins que vous souhaitez restreindre du point de vue de l'aperçu. Cela dit, il est préférable de s'assurer que votre utilisateur de service dispose d'autorisations minimales pour minimiser ce risque. à « Ouvrir dans l'aperçu de l'auteur ». Cela rendra la génération et la distribution de liens encore plus faciles à évangéliser.

Félicitations

Crédit pour l'implémentation du servlet et la preuve de concept à mon talentueux ami Paul Bjorkstrand

Photo de bannière par Riccardo Annandale sur Unsplash

Bon codage, vous tous.






Source link