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).
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<LogicalMessageContext> { 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<Handler>
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.
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
.
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'email1).
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.
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é.
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:
<note tip>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);
</note>
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. 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.