====== JAX-*S: Handlers & Filters ====== L'objectif de ce TP est de mettre en place des intercepteurs (//handlers// et //filters//) JAX-*S. Les développements se feront dans le projet ''services'' du TP précédent (implémentation de services en JAX-WS). Les //handlers// seront à utiliser avec l'implémentation bean "code généré" (//i.e.// la première version du service cours). Ce TP pourra constituer un bonus pour le TP "implémentation de services" de sera rendu en même temps (un seul rendu pour les deux). ===== Handlers JAX-WS ===== ==== Exemple ==== Créer une classe ''fr.univlyon1.tiw.tiw1.handlers.SimpleLogHandler'' contenant le code suivant: package fr.univlyon1.tiw.tiw1.handlers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalMessageContext; import javax.xml.ws.handler.MessageContext; public class SimpleLogHandler implements LogicalHandler { private final static Logger LOG = LoggerFactory.getLogger(SimpleLogHandler.class); @Override public void close(MessageContext ctx) { } @Override public boolean handleFault(LogicalMessageContext ctx) { LOG.warn("faute"); return true; } @Override public boolean handleMessage(LogicalMessageContext ctx) { boolean outbound = (Boolean) ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); LOG.info("message " + (outbound ? "sortant" : "entrant")); return true; } } Dans la classe de configuration Spring, ajouter un bean ''simpleLogHandler''. Dans le code de mise en place du point d'accès au service de cours exposé à partir du Bean d'implémentation du service, créer une ''List'' qui contiendra le bean ''simpleLogHandler'', puis l'ajouter au point d'accès via ''setHandlers''. Déployer le service et tester l'affichage dans les logs en appelant le service avec SOAPUI. ==== Ajout d'information ==== Créer un nouveau handler qui récupère dans le header SOAP la valeur de l'élément ''user-email'' et l'injecte dans le contexte (propriété "personne.email"). Modifier le handler de log pour afficher cette propriété si elle est présente. Ajouter ce handler dans la chaîne d'interception et modifier le test soapUI de votre service de commande pour y intégrer le nouveau header et tester. Faire de même avec l'élément ''api-key'' et la propriété ''personne.key''. ==== Récupération de l'objet client et authentification ==== Créer un handler logique d'authentification qui ajoute une propriété ''demandeur'' contenant un objet ''Personne'' correspondant à la propriété ''personne.email''. Ce handler vérifie également que la clé (''personne.key'') est le miroir de l'email((ceci n'est pas un TP de sécurité)). Si ce n'est pas le cas, le handler interdit l'accès au service. Ajouter l'intercepteur dans la chaîne des services et tester. ==== Autorisation ==== Créer un handler logique qui interdit l'accès à l'opération ''facturer'' si le demandeur n'est pas un des intervenants du cours. Pour les autres opérations, l'accès sera autorisé. ==== Pseudo envoi d'un email d'inscription ==== Ajouter un champ de type ''javax.xml.ws.WebServiceContext'' dans la classe d'implémentation du service. Annoter ce champ avec ''@Resource'' afin que le contexte soit injecté via IoC. La méthode ''getMessageContext()'' permet alors de récupérer le contexte du message et les propriétés qui ont été ajoutées par les handlers. Modifier le code métier de l'opération ''inscription'' pour: - récupérer l'objet Personne depuis le contexte - envoyer un mail à cette personne et aux personnes inscrites dans le cours. L'envoi de mail sera simulé par une ligne dans le log. Seules les propriétés dont le scope est MessageContext.Scope.APPLICATION peuvent être accédées dans le bean qui code le service. Il faut donc penser à changer le scope de la propriété ''demandeur'' dans le handler d'authentification via ctx.setScope("demandeur", Scope.APPLICATION); ===== Pour aller plus loin: JAX-RS ===== [[https://docs.oracle.com/javaee/7/tutorial/jaxrs.htm|JAX-RS]] est le pendant de JAX-WS pour l'implémentation de services REST. CXF permet également de déployer des beans annotés via JAX-RS. Un système analogue aux handlers est disponible dans JAX-RS: les //filters// (//c.f.// [[http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Server|API Filters de JAX-RS]]). Exposer les personnes comme des ressources REST via JAX-RS et en limiter l'accès via un filter qui vérifiera que la présence d'une ''api-key'' dont la valeur est le miroir de l'email de la personne accédée.