Généralités
Dans les deux modes de lancement (scripts de commandes et service Windows), il est possible de fixer votre propre configuration des moteurs FreeMarker / FOP ainsi que votre propre configuration du runtime de l'APE :
- Grâce aux paramètres -Dcom.hardis.adelia.mergedocengine.freemarker.conf et -Dcom.hardis.adelia.transformxslfoengine.fop.conf, qui permettent d'indiquer respectivement le fichier de configuration Apache FreeMarker ainsi que le fichier de configuration Apache FOP. Si un ou plusieurs de ces paramètres ne sont pas présents, alors par défaut, les fichiers de configuration se trouvant dans le sous-répertoire "config" (config/freemarker.properties et config/xfop.conf) sont utilisés.
- Grâce aux fichiers de configuration application-prod.yml et application-dev.yml (se trouvant dans le sous-répertoire "config"), qui permettent d'externaliser la configuration de l'application Spring Boot Adelia Print Engine (niveau de log, port d'écoute, niveau de sécurité, etc.) ainsi que la configuration du runtime de l'APE.
Modes d'exécution
Le lancement de l'APE peut se faire suivant deux modes d'exécution :
- le mode dev (développeur) : utilisé lors du développement/mise au point de templates,
- le mode prod (production) : utilisé lors de l'exécution opérationnelle du moteur de création de documents.
Ces deux modes diffèrent dans le paramétrage de l'application Spring Boot Adelia Print Engine ainsi que du runtime de l'APE (mais utilisent par défaut la même configuration des moteurs FreeMarker / FOP).
Le mode dev
Ce mode est activé lors du lancement de l'APE via les scripts de commandes ape-dev.bat / ape-dev.sh. Il est à utiliser lorsque l'utilisateur est en phase de développement de ses templates. Ce mode s'appuie sur le fichier de configuration config/application-dev.yml (fichier de configuration au format YAML).
Avec ce profil, certains comportements sont fixés par défaut :
- Port HTTP de l'application fixé à "8080" (propriété server.port),
- Niveau de log applicatif fixé à "INFO" (propriété logging.level.ROOT),
- La journalisation des traces applicatives s'affiche dans la console (propriété logging.config),
- Aucun mécanisme d'authentification à l'appel des services Web proposés par l'API REST.
Pour plus de détails, se référer à la documentation Spring Boot.
Le mode prod
Ce mode est activé lors du lancement de l'APE via les scripts de commandes ape-prod.bat / ape-prod.sh. Il est à utiliser lorsque l'utilisateur veut exécuter l'APE en production. Ce mode s'appuie sur le fichier de configuration config/application-prod.yml (fichier de configuration au format YAML).
Avec ce profil, certains comportements sont fixés par défaut :
- Port HTTP de l'application fixé à "8080" (propriété server.port),
- Niveau de log applicatif fixé à "WARN" (propriété logging.level.ROOT),
- La journalisation des traces applicatives s'affiche dans la console (propriété logging.config),
- Activation de l'authentification par jeton JWT pour l'utilisation des API REST (propriété ape.security.enabled).
Pour plus de détails, se référer à la documentation Spring Boot.
Activation de SSL / HTTPS
Il est possible d'imposer l'utilisation d'une connexion sécurisée par certificat pour l'accès aux services Web de l'APE. Pour cela, il est nécessaire de fixer à "true" la propriété server.ssl.enabled et de renseigner les propriétés sous-jacentes permettant de décrire les caractéristiques du certificat d'authentification.
Remarque : La propriété server.ssl.key-store représente le chemin du fichier keystore contenant le certificat. Ce chemin peut etre absolu ou relatif (au répertoire parent du sous-répertoire "config"). Voici deux exemples de syntaxe :
- file:///C:/certificates/ape_https.p12,
- file:./config/ape_https.jks
Activation de l'authentification
L'authentification est un mécanisme permettant d'autoriser l'appel aux services Web proposés par l'API REST aux seuls utilisateurs identifiés. Dans ce cas, l'appel à un service Web par un utilisateur anonyme ou non authentifié est rejeté (code HTTP retourné 403).
L'activation de l'authentification par jeton JWT se fait avec la propriété ape.security.enabled. L'authentification est activée par défaut. Celle-ci peut fonctionner aussi bien en HTTP qu'en HTTPS.
Remarque : pour les utilisateurs qui ne sont pas intéressés par l'authentification des services Web de l'APE, il suffit de le désactiver en fixant la propriété ape.security.enabled à "false" dans le fichier de configuration application-prod.yml.
Rôles
L'APE permet de gérer plus finement l'accès aux services Web mergedoc et mergeandtransform, en gérant en plus l'autorisation d'exécution d'un template donné, grâce à la notion de rôle. Un rôle (une chaîne de caractères) est une propriété standardisée d'un jeton JWT qui symbolise un ou plusieurs droits d'utilisation (en fonction de la politique de sécurité définie). Dans le contexte de l'APE, un rôle définit un droit d'accès à une ressource : un template. L'APE offre un mécanisme d'association d'un template (défini par son chemin qui est constitué de leur espace de nom ainsi que leur nom) à une liste de rôles. Ce chemin est déduit des informations JSON fournies en entrée lors de l'appel des services Web :
- via les attributs namespace et templateName pour le service Web mergedoc,
- via les attributs merge.namespace et merge.templateName pour le service Web mergeandtransform.
Ainsi, si l'utilisateur demande l'accès à un template (via une requête authentifiée - c'est-à-dire possédant un jeton JWT valide) dont le chemin est présent dans l'association, son accès sera autorisé seulement si un des rôles du jeton JWT founi est présent dans la liste des rôles associés au chemin.
L'association chemin/liste de rôles est définie via la propriété ape.security.template-role-map : elle prend la forme d'une map au format YAML et permet d'associer des clés (un chemin) à une liste de valeurs (une liste de rôles).
L'expression du chemin prend la forme d'une expression générique qui permet de décrire un ou plusieurs chemins : il est ainsi possible d'associer un ou plusieurs chemins à une liste de rôles.
Les chemins peuvent être exprimés en utilisant deux syntaxes différentes :
- soit via une expression régulière. Dans ce cas, sa syntaxe est "[regex:<expression regulière validant un ou plusieurs chemins>]",
- soit via un "glob pattern". Dans ce cas, sa syntaxe est "[glob:<glob pattern validant un ou plusieurs chemins>]",
Exemple : Soit l'architecture de template suivante, stockant les éditions de deux sociétés my.company1 et my.company2
Dans ce cas d'usage, il a été défini plusieurs rôles donnant accès aux templates de la manière suivante :
- le rôle COMPANY2_ALL_DOCS permet l'accès à tous les documents de my.company2, soit les chemins de templates my/company2/brochure.ftlx et my/company2/logistics/delivery.ftlx,
- le rôle COMPANY1_STOCK permet l'accès au document stock du service production de my.company1, soit le chemin de template my/company1/production/stock.ftlx,
- le rôle COMPANY1_FINANCE_MARKETING permet l'accès à tous les documents des services finance et marketing, soit les chemins de templates my/company1/finance/report.ftlx et my/company1/marketing/campaign.ftlx,
- le rôle COMPANY1_RESEARCH_CONSULTING_A_B permet l'accès aux documents des prospects customerA et customerB du service consulting ainsi qu'à tous les documents du service research, soit les chemins de templates my/company1/consulting/customerA.ftlx, my/company1/consulting/customerB.ftlx, my/company1/research/prototype.ftlx et my/company1/research/projectX/planning.ftlx,
- le rôle COMPANY1_CONSULTING_ALL_BUT_A_B permet l'accès aux documents des prospects autres que customerA et customerB du service consulting, soit les chemins de templates my/company1/consulting/customerC.ftlx et my/company1/consulting/customerCbis.ftlx.
L'intégration des rôles dans l'APE se traduit par la définition d'une association d'expression de chemins de templates et de rôles via la propriété ape.security.template-role-map dans le fichier application-prod.yml de la façon suivante :
Fichier application-prod.yml |
---|
Expression des chemins avec la syntaxe Glob ape: template-role-map: "[glob:my/company2/**]" : [COMPANY2_ALL_DOCS] "[glob:my/company1/production/stock.ftlx]": [COMPANY1_STOCK] "[glob:my/company1/{finance,marketing}/*.*]": [COMPANY1_FINANCE_MARKETING] "[glob:my/company1/consulting/customer[AB].ftlx]": [COMPANY1_RESEARCH_CONSULTING_A_B] "[glob:my/company1/research/**]": [COMPANY1_RESEARCH_CONSULTING_A_B] "[glob:my/company1/consulting/customer[!AB]*.ftlx]": [COMPANY1_CONSULTING_ALL_BUT_A_B] |
Expression des chemins avec la syntaxe Regex ape: template-role-map: "[regex:my/company2/((?:[^/]*(?:/|$))*)]" : [COMPANY2_ALL_DOCS] "[regex:my/company1/production/stock.ftlx]": [COMPANY1_STOCK] "[regex:my/company1/(finance|marketing)/([^/]*)\\.([^/]*)]": [COMPANY1_FINANCE_MARKETING] "[regex:my/company1/consulting/customer[AB]\\.ftlx]": [COMPANY1_RESEARCH_CONSULTING_A_B] "[regex:my/company1/research/((?:[^/]*(?:/|$))*)]": [COMPANY1_RESEARCH_CONSULTING_A_B] "[regex:my/company1/consulting/customer[^AB]([^/]*)\\.ftlx]": [COMPANY1_CONSULTING_ALL_BUT_A_B] |
Jeton JWT
L'APE propose deux modes de validation de jetons JWT :
- Validation à partir d'une clé publique : vous avez en votre possession la clé publique (sous la forme d'un certificat) qui va de pair avec la clé privée ayant servi à encrypter la signature du jeton JWT,
- Validation à partir d'une JWK (JSON Web Key) contenue dans un JWKS (JWK Set) : le jeton a deux claims "kid" et "iss" supplémentaires permettant de récupérer la clé publique qui va de pair avec la clé privée ayant servi à encrypter la signature du jeton JWT.
Validation à partir d'une clé publique
Il est possible de définir les caractéristiques du jeton JWT attendu.
- La propriété ape.security.jwt.algorithm permet de définir l'algorithme d'encryptage du jeton ("RSA256" par défaut).
- La propriété ape.security.jwt.user-role-claim permet de définir le nom du claim role ("roles" par défaut).
- La propriété ape.security.jwt.keystore-type permet de définir le type de key store ("JKS" par défaut).
- La propriété ape.security.jwt.keystore-file permet de définir le fichier contenant les clés d'encryptage du jeton (valeur par défaut : le fichier "RSJwtSecurity.key" fourni par Hardis pour son serveur d'authentification jwtStandalone).
- La propriété ape.security.jwt.keystore-alias permet de définir le nom d'alias du fichier contenant les clés d'encryptage du jeton (valeur par défaut : le fichier "jwtProviderKey").
Attention :
Validation à partir d'une JWK
Il est possible de définir les caractéristiques du mécanisme de récupération des JWK contenant les clés publiques.
- La propriété ape.security.jwks.trusted-issuers-list permet de définir la liste d'un ou plusieurs fournisseurs de confiance (trusted issuers), sous la forme d'une ou plusieurs URI. Pour rechercher le JWK associé au token JWT, le claim "iss" du token doit figurer dans la liste des fournisseurs de confiance.
- La propriété ape.security.jwks.connect-timeout permet de définir le temps d'attente maximal en millisecondes pour les connexions aux fournisseurs (issuers) URI et JWK URI (-1 par défaut : temps d'attente infini).
- La propriété ape.security.jwks.read-timeout permet de définir le temps d'attente maximal en millisecondes pour la lecture du contenu des connexions aux fournisseurs (issuers) URI et JWK URI (-1 par défaut : temps d'attente infini).
- La propriété ape.security.jwk-cache-size permet de définir la taille du cache de JWK (5 par défaut).
- La propriété ape.security.jwk-expires-in permet de définir la durée maximale de rétention d'une JWK dans le cache. Cette durée s'exprime sous la forme d'une chaîne alphanumérique au format de durée ISO-8601 ("PT10H" par défaut : 10 heures).
- La propriété ape.security.retry-on-error permet, si la validation de la signature du jeton échoue, de réessayer le processus de validation en rechargeant le fournisseur (issuer) URI et les JWK, et en créant de nouveaux caches ("true" par défaut).
Serveur d'authentification autonome
Adélia Studio fournit un serveur d'authentification compatible avec l'APE. Ce service (ou serveur) d'authentification peut-être déployé de façon autonome.
Pour cela, il faut copier le fichier %adeliws%/javarun/jwtProviderStandAlone/jwtProviderStandAlone.war à l'emplacement ad hoc du serveur d'applications (Tomcat par exemple).
Configuration
La configuration du service se fait via un fichier (jwtProv.properties) externalisé sous la forme d'une ressource jndi de type URL via l'alias url/jwtProv avec une fabrique pointant sur la classe com.hardis.common.JndiURLPropsFactory.
Exemple :
Déclaration d'une ressource jndi de nom url/jwtProv de type URL utilisant la fabrique com.hardis.common.JndiURLPropsFactory.
L'emplacement du fichier jwtProv.properties contenant les informations de configuration du service est fixé à l'aide de l'URL : file:///d:/extcfg/jwtProv.properties
Dans le sous-répertoire de l'application web jwtProviderStandAlone installée, créer un fichier META-INF\context.xml :
<Context> <Resource auth="Container" factory="com.hardis.common.JndiURLPropsFactory" name="url/jwtProv" type="java.net.URL" url="file:///d:/extcfg/jwtProv.properties"/> </Context>
Le fichier jwtProv.properties référencé doit déclarer les valeurs pour les propriétés des objets JwtProviderConfig et JwtJEELoginModule, de la façon suivante :
;jwtProviderConfig jwtProviderConfig.jwtUserRoleClaim=roles jwtProviderConfig.jwtValidityTimeClaim=iat jwtProviderConfig.jwtTtl=3600 jwtProviderConfig.jwtIssuer=jwtIssuer jwtProviderConfig.jwtPrefixId=jwtId_ jwtProviderConfig.jwtAudienceKind=RscServers jwtProviderConfig.jwtAudience=http://srvapis1.com/apis ;http://srvapis2.com/apis jwtProviderConfig.jwtLoginModuleName=jwtJEELoginModule ;jwtJEELoginModule jwtJEELoginModule.userParameterName=login jwtJEELoginModule.passwordParameterName=password jwtJEELoginModule.securityRoles=ADMIN,USER jwtJEELoginModule.securityRequestUrl=
Le service requiert également un Keystore pour le chiffrement du jeton. Ce Keystore est de facto externalisé sous la forme d'une ressource jndi de type URL utilisant la fabrique com.hardis.common.JndiURLFactory via l'alias url/adelRSJwtSecurity.
Exemple :
Déclaration d'une ressource jndi de nom url/adelRSJwtSecurity de type URL utilisant la fabrique com.hardis.common.JndiURLFactory.
L'emplacement du Keystore est fixé à l'aide de l'URL : file:///d:/extcfg/RSJwtSecurity.key
<Context> <Resource auth="Container" factory="com.hardis.common.JndiURLPropsFactory" name="url/jwtProv" type="java.net.URL" url="file:///d:/extcfg/jwtProv.properties"/> <Resource auth="Container" factory="com.hardis.common.JndiURLFactory" name="url/adelRSJwtSecurity" type="java.net.URL" url="file:///d:/extcfg/RSJwtSecurity.key "/> </Context>
Un Keystore par défaut (nommé RSJwtSecurity.key), contenant les clés de l'algorithme de chiffrement asymétrique RSA256 et permettant de chiffrer ou de valider un jeton, est livré par défaut dans le répertoire config de la distribution standard de l'APE (%ADELIWS%\distrib\AdeliaPrintEngine).
Le même Keystore doit être utilisé par le service d'authentification (chiffrement du jeton) et par l'APE (validation du jeton).
Le Keystore fourni par défaut peut-être remplacé par un autre Keystore qu'il faut créer à l'aide de la commande suivante :
java -cp jwtProvider-{version}.jar;bcprov-jdk15-1.45.jar com.hardis.jwtprovider.JwtKeyTool -generate pathto\RSJwtSecurity.key
Le service requiert ensuite d'associer les utilisateurs (leurs credentials) aux rôles.
Exemple :
La déclaration des utilisateurs et des rôles sous Tomcat se fait dans le fichier de configuration conf\tomcat-users.xml.
<?xml version='1.0' encoding='cp1252'?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0"> <role rolename="ADMIN"/> <role rolename="USER"/> <user username="bobTheUser" password="bob" roles="USER"/> <user username="johnTheAdmin" password="john" roles="ADMIN"/> </tomcat-users>
Enfin le service d'authentification autonome requiert par défaut un transport sécurisé (HTTPS). Une configuration doit par conséquent être mise en œuvre au niveau du Container Java EE pour satisfaire ce besoin.
Remarque :
Pour désactiver le transport sécurisé, commenter la section <security-constraint> dans le fichier WEF-INF\web.xml de l'application web jwtProviderStandAlone installée.
Création d'un jeton
Le service a pour rôle d'authentifier un utilisateur et, en cas de succès de l'authentification, de lui délivrer un jeton JWT (qui sera validé par l'APE en utilisant le mode de validation à partir d'une clé publique).
A l'aide de ce dernier, et pendant toute la période de validité du jeton, l'utilisateur peut s'authentifier auprès du serveur de ressources et accéder aux ressources qui lui sont autorisées.
Le service d'authentification est accessible via la Servlet nommée JWTServlet. Les identifiants de connexion (credentials) sont passés en paramètres de la requête.
Exemple :
https://host:port/wtProviderStandAlone/JWTServlet?login=user&password=pwd
Remarque : Il est également possible d'appeler la servlet en POST et de lui transmettre les identifiants de connexion dans le corps (payload) de la requête à la manière d'un formulaire HTML.
Pour des raisons évidentes de sécurité, l'utilisation du protocole HTTPS est fortement conseillée pour accéder à la Servlet JWTServlet.
La partie authentification propose différents modules : un module d'authentification LDAP, un module d'authentification Java EE et un module d'authentification Adélia.
Il est possible de chaîner plusieurs modules d'authentification.
Le choix du ou des modules se fait via la propriété jwtLoginModuleName de l'objet JwtProviderConfig, décrit dans le fichier de configuration /WEB-INF/beans.xml de l'application hébergeant le service d'authentification.
Si le module d'authentification reconnaît l'utilisateur, la phase de création du jeton JWT entre en jeu.
Celle-ci repose sur :
- Des informations retournées par le module d'authentification (nom de l'utilisateur authentifié, attributs supplémentaires optionnels liés à l'utilisateur).
- Des informations issues de l'objet JwtProviderConfig décrit dans le fichier de configuration /WEB-INF/beans.xml de l'application.
- Une clé de chiffrement nécessaire pour signer numériquement le jeton.
Cette clé de chiffrement est fournie par un keystore au format JKS nommé RSJwtSecurity.key ; le Keystore est externalisé sous forme d'une ressource jndi de type URL via l'alias url/adelRSJwtSecurity utilisant la fabrique com.hardis.common.jndiURLFactory.
En cas d'échec de l'authentification, le service retourne dans le corps de sa réponse, non plus un jeton JWT, mais une chaîne commençant par [ERROR], suivie d'un message explicatif. ↑ Haut de page
Gestion des scripts de commandes
Les scripts de trouvant dans le sous-répertoire "bin" permettent de lancer l'APE. Sous Windows, il faut utiliser les scripts ape-XXX.bat et sous Linux les scripts ape-XXX.sh.
Remarque : Sous Linux, les scripts fournis ne sont pas exécutables directement. Il faut donc soit leur ajouter l'attribut exécutable via chmod +x ape-XXX.sh soit les lancer via la commande "bash ./ape-XXX.sh".
Pour afficher l'aide sur ces scripts de commande il faut utiliser l'option "-h"n comme par exemple ape-dev.bat -h. De plus, pour ces quatre scripts, il est possible de fixer votre propre configuration des moteurs FreeMarker / FOP :
- en utilisant l'option au lancement du script -Dcom.hardis.adelia.mergedocengine.freemarker.conf="<path_to_directory_conf>", où "path_to_directory_conf" est un chemin vers un répertoire contenant le fichier de configuration FreeMarker freemarker.properties (guillemets pour les chemins avec espaces),
- en utilisant l'option au lancement du script -Dcom.hardis.adelia.transformxslfoengine.fop.conf="<path_to_directory_conf>", où "path_to_directory_conf" est un chemin vers un répertoire contenant le fichier de configuration Apache FOP fop.xconf (guillemets pour les chemins avec espaces),
- en ne spécifiant aucune des deux options décrites ci-dessus. Dans ce cas, les fichiers de configuration se trouvant dans le répertoire "config" sont utilisés.
De plus, il est possible de changer dans la ligne de commande le port d'écoute de l'application Spring Boot elle-même, via l'option "-Dserver.port=<port_number>", où "port_number" est le numéro de port HTTP défini pour l'application J2EE. La valeur par défaut est 8080 et elle est définie dans le fichier de configuration associé config/application-XXX.yml.
Pour lancer l'application en tant que service Windows, il faut utiliser le script apeService.bat. ↑ Haut de page
Gestion du service Windows
Active automatiquement le mode prod.
Le script apeService.bat permet d'installer, de désinstaller, de démarrer et d'arrêter l'application APE en tant que service Windows. Ce script doit se lancer dans une fenêtre de commande DOS exécutée en tant qu'administrateur.
Pour rendre le service opérationnel, il est nécessaire de l'installer, puis de le démarrer. Lancer la commande apeService.bat sans paramètres pour voir les options disponibles :
- install : Commande d'installation de l'application. C'est lors de cette étape que l'on peut spécifier des fichiers de configuration autres que ceux par défaut.
- start : Commande de démarrage de l'application,
- stop : Commande d'arrêt de l'application,
- uninstall : Commande de désinstallation de l'application (avec arrêt automatique de l'application avant désinstallation).
Il faut noter que l'APE démarré en mode service est lancé dans le mode d'exécution prod (pour la production).
De plus, par défaut, l'application s'appuie sur les fichiers de configuration (freemarker.properties et fop.xconf) présents dans le sous-répertoire "..\config" (relativement au répertoire bin contenant le script apeService.bat).
Pour spécifier un autre répertoire contenant les fichiers de configuration, utilisez les options d'installation comme ceci :
apeService.bat "mon service ape" -install -JVMoptions "-Dcom.hardis.adelia.mergedocengine.freemarker.conf=c:\my conf dir" "-Dcom.hardis.adelia.transformxslfoengine.fop.conf=c:\my conf dir"
Par défaut, deux fichiers de journalisation (contenant les journaux de sortie et d'erreur de la console) nommés <nom du service>_out.log et <nom du service>_err.log sont créés dans le sous-répertoire "bin" (contenant le script apeService.bat). ↑ Haut de page