Méthodes d'utilisation de sessions HTTP recommandées
Cette rubrique présente les méthodes recommandées pour implémenter des sessions HTTP.
- Intégration de la sécurité pour sécuriser les sessions HTTP
Les sessions HTTP sont identifiées par des ID session. Un ID session est un numéro choisi de manière aléatoire et généré lors de la phase d'exécution. Les vols de session (session hijacking) touchent fréquemment les sessions HTTP. Toutefois, il est possible d'éviter ce type d'attaque si toutes les demandes du réseau sont acheminées via une connexion sécurisée (c'est-à-dire HTTPS). Malheureusement, toutes les configurations de l'environnement utilisateur n'appliquent pas cette règle car les connexions SSL ont une incidence sur les performances. En raison de leurs règles de sécurité moins rigides, les sessions HTTP peuvent facilement faire l'objet d'attaques. Face à cette vulnérabilité, WebSphere Application Server offre la possibilité d'associer étroitement les sessions HTTP à la sécurité WebSphere Application Server. Activez la sécurité dans WebSphere Application Server pour que les sessions soient protégées et que seuls les utilisateurs qui ont créé les sessions puissent y accéder.
- Libérez les objets HttpSession à l'aide de la méthode
javax.servlet.http.HttpSession.invalidate() lorsqu'ils ne sont plus utilisés.Les objets HttpSession survivent à l'intérieur du conteneur Web jusqu'à ce que :
- L'application les libère explicitement par un appel programmé de la méthode javax.servlet.http.HttpSession.invalidate ; l'invalidation programmée fait souvent partie de la fonction de déconnexion (logout) d'une application.
- Le produit WebSphere Application Server détruit l'objet HttpSession alloué lorsqu'il expire (au terme d'un délai qui, par défaut, est de 1800 secondes, soit 30 minutes). WebSphere Application Server ne peut gérer qu'un certain nombre de sessions HTTP en mémoire en fonction des paramètres de gestion des sessions. Dans le cas de sessions réparties, lorsque la cache des sessions a atteint sa taille maximale, l'utilitaire de gestion de session supprime la session la plus ancienne de la cache afin de laisser place à la nouvelle.
- Ne tentez pas de sauvegarder et de réutiliser l'objet HttpSession en dehors de chaque servlet ou fichier JSP.
L'objet HttpSession est une fonction de la classe HttpRequest (vous ne pouvez l'obtenir que par un appel de la méthode req.getSession). Tout exemplaire de HttpSession n'est valide que pendant la durée de vie de la méthode service du servlet ou du fichier JSP concerné. Autrement dit, vous ne pouvez pas stocker un objet HttpSession en cache et le référencer ensuite en dehors de la portée d'un servlet ou d'un JSP.
- Implémentez l'interface java.io.Serializable lors du développement de nouveaux objets destinés à être stockés dans la session HTTP.
La sérialisabilité d'une classe est activée par la classe qui implémente l'interface java.io.Serializable. L'implémentation de l'interface java.io.Serializable permet la sérialisation correcte de l'objet lors de l'utilisation de sessions réparties. Les classes qui n'implémentent pas cette interface ne pourront voir leurs états sérialisés ou dé-sérialisés. C'est pourquoi, si une classe n'implémente pas l'interface Serializable, la machine JVM n'est pas en mesure de faire passer son état vers une base de données ou vers une autre machine JVM. Tous les sous-types d'une classe sérialisable sont sérialisables. Voici un exemple :
public class MyObject implements java.io.Serializable {...}
Assurez-vous que toutes les variables d'instance qui ne sont pas marquées comme étant transitoires sont sérialisables. Un objet non-sérialisable ne peut être mis en mémoire cache.
En accord avec la spécification Java™ Servlet, le conteneur de servlet distribué doit créer une IllegalArgumentException pour les objets lorsque le conteneur ne peut prendre en charge le mécanisme nécessaire pour la migration de la session qui les héberge. Une exception est créée uniquement si vous avez sélectionné distribuable.
- Utilisez <codeph>write frequency=END_OF_SERVICE</codeph> lors de l'activation de la reprise en ligne de l'état de session afin d'éviter la perte de données durant la reprise avec la base de données ou WebSphere eXtreme Scale. La perte de données est évitée car les données de session sont stockées dans la base de données ou la grille de données à la fin de chaque demande. Ce comportement a pour conséquence des temps de demande plus longs, ce qui dégrade les performances.
- Assurez-vous que les objets Java ajoutés à une session se trouvent dans le chemin de
classe correct.
Si vous ajoutez des objets Java à une session, placez les fichiers classe de ces objets dans le chemin de classe correct (le chemin d'accès aux classes de l'application si vous utilisez le partage entre modules Web dans une application d'entreprise, ou le chemin d'accès aux classes du module Web si vous utilisez le partage de session conforme à la spécification Servlet 2.2) ou dans le répertoire contenant d'autres servlets utilisés dans WebSphere Application Server. Dans le cas d'un groupage de sessions, cette action s'applique à tous les noeuds du cluster.
L'objet HttpSession étant partagé entre les servlets auxquels l'utilisateur est susceptible d'accéder, il est conseillé d'utiliser une convention de dénomination unique pour l'ensemble du site afin d'éviter des conflits.
- Evitez de stocker des graphiques d'objets volumineux dans l'objet HttpSession.
Dans la plupart des applications, chaque servlet n'a besoin que d'une petite partie des données de session. Toutefois, si ces données sont stockées dans l'objet HttpSession sous la forme d'un seul objet de grande taille, l'application force WebSphere Application Server à traiter chaque fois cet objet dans son intégralité.
- Utilisez l'affinité des sessions pour atteindre des taux de réussite en mémoire cache plus élevés dans WebSphere Application Server.
Le produit WebSphere Application Server est doté d'une fonctionnalité dans le plug-in HTTP Server, qui est utile pour l'affinité des sessions. Le plug-in lit les données des cookies (ou l'URL codée) à partir du navigateur et aide à acheminer la requête vers l'application ou le clone approprié en fonction de la clé de session attribuée. Cette fonctionnalité augmente l'utilisation de la mémoire cache et réduit les accès à la base de données ou à une autre instance WebSphere Application Server.
- Tirez parti au maximum de l'affinité de session et évitez d'interrompre l'affinité.
L'utilisation correcte de l'affinité de session peut améliorer les performances de WebSphere Application Server. L'affinité de session dans l'environnement WebSphere Application Server permet de maximiser la mémoire cache des objets session et de réduire la quantité de lectures de la base de données ou d'une autre instance WebSphere Application Server. Elle fonctionne via la mise en cache des objets session dans l'instance de serveur de l'application avec laquelle un utilisateur dialogue. Si l'application est déployée dans plusieurs serveurs d'un groupe de serveurs, l'application peut diriger l'utilisateur vers n'importe lequel des serveurs. Si l'utilisateur commence par le serveur 1, puis utilise le serveur 2 un peu plus tard, le serveur doit écrire toutes les informations de session dans l'emplacement externe, de sorte que l'instance du serveur dans laquelle le serveur 2 est en cours d'exécution puisse lire la base de données. Vous pouvez éviter cette lecture de base de données en utilisant l'affinité de session. Grâce à l'affinité de session, l'utilisateur commence par le serveur 1 pour la première requête ; puis, pour chaque nouvelle requête, il est renvoyé au serveur 1. Le serveur 1 doit consulter uniquement la mémoire cache pour obtenir les informations de session ; il n'est jamais nécessaire que le serveur 1 appelle la base de données de session pour extraire les informations.
Vous pouvez améliorer les performances en évitant de rompre l'affinité de session. Voici quelques suggestions à ce propos :- Si possible, regroupez toutes les applications Web en une instance de serveur d'applications unique, puis utilisez la modélisation et le clonage pour fournir un support de fonction de secours.
- Créez la session pour la page du cadre principal, mais n'en créez pas d'autres pour les pages du cadre lors de l'utilisation des fichiers JSP multicadres. (Voir la discussion à ce propos, plus loin dans cet article.)
- Lors de l'utilisation de pages multicadres, suivez les instructions ci-dessous :
- Créez une session dans un seul cadre ou avant d'accéder à des ensembles de cadres. Supposons, par exemple, qu'aucune session n'est déjà associée au navigateur et qu'un utilisateur accède à un fichier JSP multicadres, le navigateur émet des demandes simultanées pour les fichiers JSP. Dans la mesure où les demandes ne font partie d'aucune session, les fichiers JSP finissent par créer plusieurs sessions et tous les cookies sont renvoyés au navigateur. Le navigateur honore uniquement le dernier cookie qui arrive. Par conséquent, seul le client peut extraire la session associée au dernier cookie. Il est conseillé de créer une session avant d'accéder aux pages multicadres qui utilisent des fichiers JSP.
- Par défaut, les JSP obtiennent un HTTPSession en utilisant la méthode request.getSession(true). Ainsi, les fichiers JSP créent, par défaut, une session s'il n'en existe aucune pour le client. Chaque page JSP chargée dans le navigateur demande une nouvelle session, mais une seule session est utilisée par instance de navigateur. Un développeur peut utiliser <% @ page session="false" %> pour éteindre la création de session automatique à partir des fichiers JSP qui n'accèdent pas à la session. Ensuite, si la page a besoin d'accéder aux informations de session, le développeur peut utiliser <%HttpSession session = javax.servlet.http.HttpServletRequest.getSession(false); %> pour obtenir la session existante qui a été créée par le fichier JSP original de création de session. Vous évitez ainsi de rompre l'affinité de session au chargement initial des pages de cadre.
- Mettez à jour les données de session à l'aide d'un seul cadre. Lors de l'utilisation des ensembles de cadres, les requêtes arrivent simultanément dans le serveur HTTP. Il est conseillé de modifier les données de session dans un seul cadre, de sorte que les modifications de session ne soient pas remplacées par des modifications de session de l'ensemble de cadres concurrent.
- Evitez d'utiliser des fichiers JSP multicadres dans lesquels les cadres pointent sur des applications Web différentes. Cette action entraîne la perte de la session créée par une autre application Web, car le cookie JSESSIONID de la première application Web est remplacé par le cookie JSESSIONID créé par la seconde application Web.
- Lors de l'application de la sécurité aux servlets et aux fichiers JSP qui utilisent des sessions avec l'intégration de sécurité intégrée, sécurisez toutes les pages (et non pas seulement certaines d'entre elles).
En matière de sécurité et de sessions, c'est tout ou rien! En effet, il ne sert à rien de protéger l'accès à l'état des sessions à certains moments et pas à d'autres. Lorsque l'intégration de la sécurité est activée dans l'utilitaire de gestion de sessions, toutes les ressources à partir desquelles une session est créée ou utilisées pour accéder à cette session doivent être soit sécurisées, soit libres d'accès. Vous ne pouvez pas combiner des ressources sécurisées et des ressources non sécurisées.
Le problème qui se pose avec la sécurisation partielle est que les sessions créées dans des pages sécurisées sont créées sous l'identité de l'utilisateur autorisé. Seul cet utilisateur peut accéder aux sessions dans d'autres pages sécurisées. Pour interdire aux utilisateurs non autorisés l'utilisation de ces sessions, ces dernières ne sont pas accessibles à partir d'une page non sécurisée. Lorsqu'une demande est reçue d'une page non sécurisée, l'accès est refusé et une erreur UnauthorizedSessionRequestException est générée. (UnauthorizedSessionRequestException est une exception d'exécution. Elle est consignée par vous.)
- Utilisez la mise à jour manuelle et la méthode sync() ou l'écriture périodique dans les applications qui lisent les données de session et les mettent à jour rarement.
Avec END_OF_SERVICE comme fréquence d'écriture, lorsqu'une application utilise des sessions et chaque fois que des données sont lues ou écrites dans cette session, la zone LastAccess (heure de dernier accès) est mise à jour. Si les sessions de base de données sont utilisées, une nouvelle écriture dans la base de données est générée. Vous pouvez éviter cet impact négatif sur les performances en utilisant l'option de mise à jour manuelle et en programmant l'écriture de l'enregistrement dans la base de données uniquement lorsque des données sont mises à jour, et non à chaque lecture ou écriture de cet enregistrement.
Pour utiliser la mise à jour manuelle, vous devez l'activer dans l'utilitaire de gestion de session. (Pour plus d'informations sur l'emplacement, reportez-vous aux tableaux précédents.) De plus, le code de votre application doit utiliser la classe com.ibm.websphere.servlet.session.IBMSession à la place de la classe générique HttpSession. L'objet IBMSession contient la méthode sync. Cette méthode demande à WebSphere Application Server d'écrire les données de l'objet session dans la base de données. Vous pouvez ainsi améliorer les performances globales en ne faisant persister les informations de la session que lorsque cela est nécessaire.
Remarque : Pour utiliser les mises à jour manuelles, vous avez également la possibilité de faire appel aux mises à jour temporelles de manière à assurer la persistance des données à des intervalles de temps différents. Les résultats sont similaires à ceux de la mise à jour manuelle. - Voici quelques suggestions qui vous permettront d'obtenir les meilleures performances :
- Si vos applications ne modifient pas souvent les données de session, utilisez la mise à jour manuelle et la fonction sync (ou la mise à jour temporisée) pour rendre plus efficace la persistance des informations de session.
- Faites en sorte que la quantité de données stockées dans la session soit aussi petite que possible. Le stockage de données dans les sessions étant facile à mettre en oeuvre, les développeurs ont parfois tendance à en abuser et à stocker une trop grande quantité de données dans les objets session. Pour utiliser efficacement les sessions, déterminez un juste compromis entre stockage des données et performances.
- Si vous utilisez des sessions de base de données, faites appel à une base de données dédiée pour la base de données de session. Evitez d'utiliser la base de données de l'application. Vous éviterez ainsi les conflits d'utilisation des connexions JDBC et obtiendrez de meilleures performances d'accès à la base de données.
- Si vous utilisez des sessions mémoire à mémoire, faites appel au partitionnement (réplique unique ou de groupe) à mesure que la taille des clusters augmente et que l'évolutivité décroît.
- Vérifiez que vous disposez des derniers fix packs pour WebSphere Application Server.
- Utilisez les outils ci-dessous qui aident à surveiller les performances des sessions.
- Exécutez le servlet com.ibm.servlet.personalization.sessiontracking.IBMTrackerDebug. Pour exécuter ce servlet, le module d'appel de servlet doit s'exécuter dans l'application Web à partir de laquelle vous voulez exécuter ce servlet. Vous avez également la possibilité de configurer explicitement ce servlet dans l'application que vous souhaitez exécuter.
- Utilisez l'analyseur de ressources WebSphere Application Server qui est livré avec le produit WebSphere Application Server afin de surveiller les statistiques et les sessions actives de l'environnement WebSphere Application Server.
- Utilisez les outils de suivi de base de données, tels que "Monitoring" dans DB2. (Pour plus de détails sur le système de base de données utilisé, consultez la documentation correspondante.)