pause-café
destinée aux informaticiens sur plateforme IBM i.
Pause-café #87
TR3 - sécurité web services
TR3 (et aussi la TR9 de la 7.3)
- La dernière TR (TR3 pour 7.4 ou TR9 pour 7.3) apporte deux nouvelles fonctionnalités pour gérer la sécurité des web services
- Registre utilisateur, groupes et rôles : permet de définir des rôles associés à des utilisateurs, et d’autoriser l’appel à un service en fonction du rôle
- Trust Authentication Interceptor : permet d’authentifier un utilisateur par du code côté serveur
- Pour rappel, la liste des fonctionnalités IWS par PTF : https://www.ibm.com/support/pages/node/1138612
- Ces fonctionnalités nécessitent :
- 7.2 : SF99713 Level 40, SI75444,SI75178
- 7.3 : SF99722 Level 28, SI75443,SI75177
- 7.4 : SF99662 Level 9, SI75442,SI75176
Registre utilisateur, groupe et rôle
- Disponible pour les nouvelles instances de serveur comme pour les instances existantes
- Nécessite Java 8
- Vous pouvez modifier la version de java du serveur IWS
- Référence https://www.ibm.com/support/pages/node/6396442
- L’objectif est de fournir un mécanisme d’authentification supplémentaire par une gestion de rôles définis au niveau serveur
- Pour chaque service on indiquera les rôles autorisés
- On attache des utilisateurs et groupes d’utilisateurs à ces rôles
- Cela nécessite donc une authentification des utilisateurs : soit basée sur les profils utilisateurs, soit sur une liste de validation, et désormais par des fichiers
- L’authentification ne se fait plus par le serveur HTTP APACHE, mais par IWS
Réglage via l'interface graphique
- Dans l’interface web d’administration, une nouvelle option « Security »
- Enable User Registry: active ou non le register d’utilisateurs pour le serveur
- Realm: définit le domaine d’authentification
- Use secure connections: la communication entre IWS et l’IBM I doit elle être cryptée ? Concrètement la communication générée par le JavatoolBox. Nécessite que les services natifs soient configurés pour être cryptés
- Path to role definition file: fichier de définition des rôles
- Path to group definition file: fichier de definition des groupes
- Normalize login name case: indique s’il faut normaliser les logins avant l’authentification
- Authentification par *USRPRF : non sensible à la case
- Liste de validation et fichier : sensible à la case Valeurs : *UPPER / *LOWER / *NONE
- User registry : type de register utilisé pour l’authentification
Fichier des utilisateurs :
- Liste des utilisateurs et mot de passe associé
- Il est possible d’indiquer un mot de passe encodé par l’algorithme XOR
- Codé par une clé
- La documentation n’indique pas (encore) comment exploiter la clé encodée
Fichier des groupes :
- Facultatif
- Attachement des utilisateurs prédéfinis à des groupes
- Les utilisateurs peuvent provenir du fichier précédent, de liste de validation ou *USRPRF
- Pas d’obligation d’attacher tous les utilisateurs à des groupes
Fichier des rôles :
- Facultatif : uniquement si l’on souhaite utiliser les rôles dans l’authentification
- Définition des rôles et attachement d’utilisateurs et/ou de groupes
la modification de ces fichiers nécessite le redémarrage du serveur pour prise en compte.
Déploiement ou redéploiement d’un service :
- Secure transport required : le service (pour l’ensemble des méthodes/procédures) doit utiliser https
- Protect using authentication method :
- *NONE : pas de mécanisme d’authentification
- *BASIC : authentification HTTP basique. Dans ce cas, on indique les rôles autorisés. Les utilisateurs associés à ces rôles peuvent appeler le service
- Si l’implémentation est un programme de service, l’assistant propose pour chaque procédure les rôles autorisés (sélectionné dans les rôles autorisés au niveau service)
- On peut choisir ensuite de fonctionner avec
- Un user défini pour le service : l’authentification réalisé au niveau du service sert à valider le droit d’appeler le service
- Le code d’implémentation ne peut pas récupérer la valeur de l’utilisateur authentifié, sauf à propager la valeur d’entête Authorization
- L'utilisateur authentifié peut être différent de l'utilisateur d'exécution
- Pour exécuter le service avec l'utilisateur authentifié, il est obligatoire d'avoir défini l'authentification basique sur les profils utilisateurs (pes de fichier user.xml)
- L’utilisateur authentifié : attention à ce que les utilisateurs définis dans les fichiers de configuration group.xml et role.xml :
- existent
- disposent des droits pour éxecution
- le profil du serveur IWS dispose du droit *USE sur ces profils
Impacts sur les traces
Les informations de configuration concerant les utilisateurs, rôles et groupes apparaissent dans le fichier message.log :
Les erreurs liées à l'authentification console.log :
Réglage par script
Pour créer ou modifier une instance de serveur, les commandes createWebServicesServer.sh et setWebServicesServerProperties.sh admettent les nouveaux paramètres suivants :
- -defaultKeystore 'keystore'
- -defaultKeystorePassword 'password'
Pour déployer par script, les nouvelles propriétés suivantes sont supportées :
- Niveau service
- ws.iws.gen.authenticationmethod=*BASIC
- ws.iws.gen.authorizedrole.1=admin
- ws.iws.gen.authorizedrole.2=maj
- ws.iws.gen.securetransportrequired=false
- Niveau procédure
- ws.method.CREER.gen.authorizedrole.1=admin
- ws.method.CREER.gen.authorizedrole.2=maj
Le script shell /QIBM/ProdData/OS/WebServices/bin/getConfigurationFile.sh vous permet de générer pour vos services existants (et obtenir un modèle).
Attention : la sauvegarde d'un service par saveWebServices.sh et sa restauration par restoreWebServices.sh provoque un erreur d'authentification systématique (le paramètrage étant cohérent). Seul un redéploiement du service a pu rétablir le fonctionnement !
Live Demo
Le but de cette démo est d'observer, via un serveur IWS déjà paramétré, l'usage d'un registre utilisateur basé sur un fichier.
Nous avons donc défini :
- des rôles
- des utilisateurs
- des groupes
Et déployer un service de gestion des clients (informations d'un client, liste, création et la version de l'API).
Pour des questions de démo, nous retournons systématiquement des données techniques.
Les appels se font par POSTMAN qui permet de mémoriser et tester différentes combinaisons.
TAI - Trust authentication interceptor
- Référence https://www.ibm.com/support/pages/node/6396908
- C’est un mécanisme complémentaire permettant d’implémenter, en Java, sa propre logique d’authentification
- Concrètement, vous fournissez le code Java et pouvez donc réaliser des authentifications
- En dérogeant à l’authentification basique
- Sans authentification HTTP (au sens HTTP Basic), mais via Oauth, JWT, … ou via vos propres mécanismes de bus, passerelles, …
- Le code est invoqué par IWS directement, avant la gestion de l’authentification par utilisateur vu précédemment, et doit renvoyer une authentification
- Implémentation
- Il faut fournir une classe Java qui implémente l’interface com.ibm.wsspi.security.tai.TrustAssociationInterceptor
- Voir la documentation pour Liberty : https://www.ibm.com/support/knowledgecenter/SSD28V_liberty/com.ibm.websphere.wlp.core.doc/ae/twlp_dev_custom_tai.html
- La Javadoc : https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.javadoc.liberty.doc/com.ibm.websphere.appserver.api.security_1.3-javadoc/com/ibm/wsspi/security/tai/TrustAssociationInterceptor.html
- Cinématique
- La méthode isTargetInterceptor est invoquée
- Elle reçoit HttpServletRequest afin de pouvoir accèder à l’ensemble des propriétés de la requête (méthode, URL, entête, corps)
- Doit renvoyer true/false pour indiquer si la requête doit être interceptée ou non
- Si oui, la méthode negotiateValidateandEstablishTrust est invoquée
- Elle reçoit HttpServletRequest ET HttpServletResponse
- Doit renvoyer un objet de type TAIResult, qui contient
- Un statut : OK, FORBIDDEN, … le statut SC_OK est le seul à valider une authentification
- Un « principal » : nom de l’authentification (utilisateur)
- Un sujet JAAS contenant des informations complémentaires (cf classe javax.security.auth.Subject)
- La méthode isTargetInterceptor est invoquée
- Pour compiler votre classe personnalisée, vous devez disposer des jar suivants :
- /QIBM/ProdData/OS/ApplicationServer/runtime/wlp/dev/api/ibm/com.ibm.websphere.appserver.api.security_1.3.xx.jar
- /QIBM/ProdData/OS/ApplicationServer/runtime/wlp/dev/api/ibm/com.ibm.websphere.appserver.api.securityClient_1.1.xx.jar
- Par exemple dans RDi, ajouter les jar au chemin de compilation
Exemple de classe TAI (fournit par IBM) :
Configuration du serveur
Dans la configuration du service
- Enable TAI: active ou non TAI pour le serveur
- Interceptor class name: nom de la classe, totalement qualifiée
- Invoke TAI for unprotected applications: indique s’il faut appeler TAI pour tous les services web du serveur, ou uniquement les services web protégés
- Allow fallback to application authentication: si l’authentification TAI échoue, se baser sur l’authentification HTTP
- Libraries for interceptor: indiquer la librairie de la classe TAI ET les libraires dépendantes. Les noms génériques sont admis :
- /mytai/simpleTAI.jar
- /mytailibs/*.jar
- Interceptor properties: propriétés à transmettre à l’implémentation
Authentification cache
- Permet d’améliorer les performances
- Enable authentication cache: activer ou non le cache
- Initial cache size: taille initiale du cache (en nombre d’entrées)
- Maximum cache size: taille maximale du cache (en nombre d’entrées)
- Cache eviction timeout (seconds): durée de retention d’une entrée
Peu de documentation !
Réglage de la rétention par rapport à la durée de vos jetons par exemple Si les mécanismes d’authentification tiers nécessite d’être invoqué systématiquement, désactiver le cache
Keystore
- Permet d’indiquer le magasin par défaut pour le serveur afin de communiquer avec d’autres serveurs https
- *NONE: aucun magasin de clé
- *SYSTEM: '/QIBM/USERDATA/ICSS/CERT/SERVER/DEFAULT.KDB’
- Le profil serveur doit avoir *RX (read, execute) sur le magasin (et l’ensemble du chemin). Le mot de passe est à fournir
- Attention aux dates de péremption des certificats : vous pouvez utiliser le service IBM i QSYS2.certificate_info pour facilement contrôler vos certificats :
-
select * from table (qsys2.certificate_info(certificate_store_password => 'votreMDP') ) where validity_end < current date + 1 month;
- D’autres valeurs à venir bientôt ?
Remarques :
- La modification de l’implémentation de la classe TAI nécessite l’arrêt/redémarrage du serveur
- Liberty contient des APIs directement utilisables, par exemple
- WebSphere Security JWT Builder And Token API
- WebSphere OAuth 2.0 web single sign-on API
- Attention à la performance du code
- Impact non mesuré de façon détaillée
Live Demo
Via un autre serveur déjà configuré avec les mêmes attributs de registre utilisateur, ajout du fonctionnement avec TAI.
TAI permet d'implémenter sa propre logique d'authentification. Ici nous avons choisi une logique simplifiée d'authentification par jeton.
La mécanique est la suivante :
- Le client obtient un jeton auprès d'un service d'authentification
- Il transmet ce jeton auprès du service à invoquer
- Le service valide alors la validité du jeton auprès du service d'authentification
- Le jeton peut également porter de l'information, un profil par exemple
Nous avons donc codé un serveur d'authentification simplifié pour les besoins de démonstration, capable de créer un jeton, lister les jetons et valider un jeton.
Toujours par POSTMAN pour les appels.