4 nov. 2021 11:58:06 Thomas Dumont avatar

Authentification - SSO - MyLutece

Plusieurs API ont été mises en place à partir de la version 1.1 de Lutèce pour gérer la sécurité des accès aux ressources du portail. La principale mise en oeuvre est faite par le plugin MyLutece qui réalise de manière modulaire l'authentification et la gestion des rôles associés aux utilisateurs authentifiés du site. L'objectif de cette API est de fournir un dispostif de « SSO » (Single Sign On), c'est à dire une authentification unique des utilisateurs partagée par toutes les applications. Ceci signifie que toute application du portail pourra vérifier que l'utilisateur courant est identifié et accéder à ses rôles.

Outre l'authentification des utilisateurs, ces API permettent la réalisation d'applications basées sur des rôles : espaces privés, personalisation, préférences, rôles applicatifs, ...

API des modules d’authentification

La gestion de l’authentification est modulaire et paramétrable, de manière à supporter plusieurs implémentations dont voici une liste non exhaustive :

  • annuaire LDAP (LDAPAuthentication )
  • base de données interne (BaseAuthentication )
  • authentification déléguée au serveur Web (ex: Tomcat)

L’ensemble des implémentations doit respecter l’interface fr.paris.lutece.portal.service.security.LutecePortalAuthentication .

On distingue deux sous-ensembles d’implémentations :

  • l’authentification est assurée au niveau de Lutece.
  • l’authentification est réalisée en amont de Lutece (ex : serveur web ou WSSO).

Une authentification assurée par Lutece a les caractéristiques suivantes :

  • elle doit prévoir des méthodes de connexion/déconnexion (login / logout ).
  • elle spécialise la classe abstraite fr.paris.lutece.plugins.mylutece.authentication.PortalAuthentication .

Une authentification basée sur un système amont d’authentification disposera quant à elle des caractéristiques suivantes :

  • elle ne doit pas prévoir des méthodes de connexion /déconnexion puisque celles-ci sont assurées par le dispositif externe situé en amont.
  • elle spécialise la classe abstraite fr.paris.lutece.plugins.mylutece.authentication.ExternalAuthentication .

API des utilisateurs et gestion des comptes

A chaque système d’authentification peut être associé un modèle d’utilisateur qui doit implémenter le modèle minimal défini par l’interface fr.paris.lutece.portal.service.security.LuteceUser .

Les implémentations notamment prévues sont :

  • LDAPUser
  • BaseUser

Ces implémentations ne font pas partie du noyau, elles sont disponibles dans le plugin "mylutece" sous le package fr.paris.lutece.plugins.mylutece.modules.* .

La façon dont ces modèles d’utilisateurs délivrent les informations concernant l’utilisateur se rapproche du modèle proposé par la spécification JSR 168, basée elle-même sur celle de la Platform for Privacy Preferences 1.0réalisée par le W3C. Ainsi les noms et prénoms se récupèrent à partir des clés user.given.name et user.given.family . Les mêmes noms d'attributs sont proposés par les OASIS Web Services for Remote Portlets Technical Committee. Voir la liste des attributs

Concernant la gestion des comptes des utilisateurs, plusieurs modes sont possibles :

  • l’utilisateur ne peut pas créer lui-même un compte. La création du compte doit alors être réalisée au niveau de l’annuaire soit par une fonction d’administration intégrée à Lutece soit par un dispositif autre.
  • l’utilisateur peut se créer un compte sans nécessiter l’intervention des administrateurs du site. Dans cette situation, l’écran de login affichera un lien vers la page de création d’un nouveau compte.

Dans les deux situations, il sera possible pour l’utilisateur identifié d’accéder à une page optionnelle et paramétrable permettant de visualiser les informations du compte. A partir de cette page et en fonction des choix de gestion des comptes il est envisageable d’ajouter des fonctions de changement de mot de passe ou de modification des informations personnelles.

Concernant les rôles associés aux utilisateurs, ils correspondent à la description faite dans la spécification Java Servlet 2, c’est à dire une notion abstraite définie par une application qui, associée à un utilisateur ou à un groupe d’utilisateur, permet de définir une politique de sécurité.

Remarque importante : selon le système d’authentification utilisé, l’accès à l’ensemble des rôles n’est pas toujours possible. Par exemple, le système d’authentification basé sur le serveur web ne permet que de vérifier qu’un utilisateur dispose bien d’un rôle donné par le biais de la méthode isUserInRole , mais la liste des autres rôles n’est pas accessible.

Le nouveau service de sécurité SecurityService

Un nouveau service a été ajouté au noyau de Lutece pour assurer les fonctions de gestion des utilisateurs. Ce service est le point d’entrée pour tous les composants : plugins, portlets ou applications désirant obtenir l’identité de l’utilisateur courant.

La principale méthode à utiliser est getRegisteredUser qui permet d’obtenir l’identité de l’utilisateur courant enregistré au niveau du portail.

Une nouvelle exception UserNotSignedException a été ajoutée à la signature des méthodes getPage des interfaces ContentService et XPageApplication , afin de signifier que l’utilisateur doit être authentifié pour accéder au service ou à l’application. Cette exception est catchée par la page principale du site, Portal.jsp . Celle-ci enregistre les paramètres courants de l’url, redirige l’utilisateur vers la page de login paramétrée dans le fichier mylutece.properties . Une fois l’identification réalisée, l’utilisateur est redirigé vers l’url à laquelle il tentait d’accéder initialement :

LuteceUser user = SecurityService.getInstance().getRegisteredUser( request );
     if( user != null )
     {
           // The user is authenticated
           ...
     }
     else
     {
          // Throw an exception to force the user to login
          throw new UserNotSignedException();
     }

A l’instar des interfaces HttpServletRequest ou PortletRequest (JSR 168), SecurityService propose également les méthodes getRemoteUser , getUserPrincipal et isUserInRole .

Mise en oeuvre


Paramétrage de l’authentification : Installation du plugin mylutece

Le plugin doit être déployé comme n’importe quel plugin. Si le dispositif d’authentification utilise la base de données proposée par défaut, il faut installer la base lutece_users , déclarer un pool de connexion vers cette base et associer ce pool au plugin dans l’interface de gestion des plugins.

Paramétrage du plugin mylutece

Les paramètres décrivant l’implémentation choisie sont définis dans le fichier de configuration mylutece.properties de Lutece grâce aux propriétés suivantes :

########################################################
# Authentication management
mylutece.authentication.enable=true
mylutece.authentication.class=fr.paris.lutece.portal.service.security.LDAPAuthentication

Description des propriétés :

  • lutece.authentication.enable : détermine si le mode d’authentification de l’instance de Lutece reposera sur le SSO (obligatoire)
  • lutece.authentication.class : détermine la classe qui implémente l’authentification choisie (à renseigner si lutece.authentication.enable a la valeur true ).

Les objets de base du système


L’écran d’identification par défaut

Dans le cas d’une identification interne au portail, le plugin MyLutece propose une page d’identification par défaut :

Cette page est accessible à partir de l’adresse http://myhost/lutece/jsp/site/Portal.jsp?page=mylutece&action=login.

Son adresse et celle du traitement du formulaire d’identification sont paramétrées dans le fichier mylutece.properties comme suit :

mylutece.url.login.page=Portal.jsp?page=mylutece&action=login
         mylutece.url.doLogin=./plugins/mylutece/DoMyLuteceLogin.jsp

Le portlet d’identification

Le plugin MyLutece propose un portlet d’identification.

Lorsque l’utilisateur n’est pas identifié et que le système d’authentification est de type Portail et non externe, le portlet affiche le formulaire de connexion login/password avec des liens facultatifs vers une page de création d’un compte ou de récupération d’un mot de passe oublié.

Une fois l’utilisateur identifié, le portlet affiche un message de bienvenue ainsi que le bouton de déconnexion.

Les pages par défaut de gestion du compte

Les pages par défaut concernant la gestion de compte disponibles dans le plugin MyLutece sont les suivantes :

  • création d’un nouveau compte
  • affichage des informations personnelles
  • mot de passe perdu

Les implémentations proposées ne sont pas opérationnelles. Si de telles fonctions de gestion de compte sont à mettre en place, il faudra réaliser une XPageApp ou des JSP pour permettre leur implémentation.

Les fonctions telles que le changement de mot de passe ou la modification des informations personnelles peuvent être implémentées de la même manière et leur accès est à prévoir au niveau de la page d’affichage des informations personnelles.

Le paramétrage des URL de ces fonctions est réalisé dans le fichier mylutece.properties . L’exemple suivant montre le paramétrage d’une implémentation réalisée avec une XPageApp nommée account_manager :

mylutece.url.createAccount.page=Portal.jsp?page=account_manager&action=createAccount
    mylutece.url.viewAccount.page=Portal.jsp?page= account_manager&action=viewAccount
    mylutece.url.lostPassword.page=Portal.jsp?page= account_manager&action=lostPassword

Contrôle de l’authentification pour les applications


Il est possible de soumettre l'ensemble des accès au portail à une authentification. Dans ce cas de figure, aucune page ou application n'est accessible à un utilisateur non identifié.

Pour mettre en oeuvre ce mode de fonctionnement il faut positionner à true la propriété suivante dans le fichier mylutece.properties :

# Only authenticated users can access to the portal 
    mylutece.portal.authentication.required=true

L’authentification pour les applications


L'interface XPageSecureApplication

Chaque application peut, par le biais du plugin dans lequel elle est packagée, définir définir si elle requiert ou non une authentification.

Un nouveau paramètre est utilisé dans le fichier de définition XML du plugin, par la balise application-security-model :

<application>
           <application-class>fr.paris.lutece.plugins.securedtest.SecuredTestApp</application-class>
           <application-security-model>1</application-security-model>
     </application>

Les valeurs possibles de ce paramètre sont à ce jour :

  • 0 : aucune authentification n’est requise pour accéder à l’application (les XPageApp de la version 1.0 fonctionnent dans ce modèle par défaut).
  • 1 : une authentification est obligatoire.

Les XPageApps fonctionnant dans ce modèle doivent implémenter l’interface XPageSecureApplication .

Si ce paramètre n’est pas présent pour le plugin (cas des plugins de la v1.0), la valeur par défaut est 0.

Il est néanmoins possible d’ajouter la gestion de l’utilisateur dans les XPageApps implémentant l’ancienne interface de base XPageSecureApplication en appelant explicitement les méthodes du SecurityService pour obtenir l’identité de l’utilisateur.

Gestion de l’accès à l’application grâce aux rôles

Un autre moyen, depuis Lutèce 1.3, permet de limiter l'accès à l'application aux seuls utilisateurs disposant d'un rôle autorisé. Ce dispositif est plus simple et offre une gestion plus fine que le précédent.

Pour mettre en oeuvre cet accès restreint, il suffit de définir les rôles autorisés dans le fichier du plugin de l'application comme suit :

<application>
           <application-class>fr.paris.lutece.plugins.myplugin.MyApp</application-class>
           <application-roles>role1,role2,admin</application-roles>
     </application>

Gestion de l’utilisateur dans l’application

Lors d’une connexion à une application Lutece, il y a vérification du mode d’authentification de l’application (ou plugin).

  • Si l’application ne requiert pas d’authentification, alors l’utilisateur a accès librement aux fonctionnalités de l’application (cas actuellement du plugin contact).
  • Si dans le fichier de configuration du plugin, il a été défini que l’application devait être accessible uniquement à une population autorisée, alors les actions suivantes sont entreprises :
  • détection dans la session des paramètres d’authentification.
  • si l’utilisateur n’est pas encore authentifié, redirection vers une page d’authentification propre à Lutece commune à toutes les applications.
  • si l’utilisateur est authentifié, et l’application n’est pas autorisée pour cet utilisateur, redirection vers une page d’erreur.
  • si l’utilisateur est authentifié et l’application est autorisée pour cet utilisateur, on le redirige vers la page d’accueil de l’application.

L'implémentation de ce mécanisme est la suivante :

Dans le cas où le dispositif d'authentification est interne :

Application sécurisée de test


Un plugin "securedtestapp" a été réalisé pour tester et illustrer le comportement d’une application dont l’accès est restreint. Cette application affiche :

  • le nom du service d'authentification utilisé.
  • les informations disponibles concernant l'utilisateur.
  • les rôles éventuellement accessibles de l'utilisateur.

Récapitulatif et memento de configuration


Contexte de sécurité souhaité Paramétrage correspondant dans mylutece.properties
L'authentification du portail n'est pas gérée. Toutes les pages et applications sont publiques : mylutece.authentication.enable=false
L'ensemble du portail doit être soumis à une authentification : mylutece.authentication.enable=true mylutece.authentication.class=< classe module authentification > mylutece.portal.authentication.required=true
L'application nécessite impérativement une authentification mais sans recourir à une gestion des rôles des utilisateurs : Dans mylutece.properties :

mylutece.authentication.enable=true mylutece.authentication.class=< classe module authentification > |

Dans le fichier XML du plugin de l'application :

<application-security-model>1</application-security-model>

L'application nécessite impérativement une authentification et n'est accessible qu'à des utilisateurs disposants de rôles particuliers : mylutece.authentication.enable=true mylutece.authentication.class=< classe module authentification >

Dans le fichier XML du plugin de l'application : <application-roles>role1,role2,admin</application-roles>|

Certaines parties de l'application sont gérées en fonction de rôles associés aux utilisateurs : mylutece.authentication.enable=true mylutece.authentication.class=< classe module authentification >

Dans le code de l'application :

  • Tester si l'utilisateur dispose du rôle pour la fonction donnée avec "isUserInRole()"
  • Forcer l'authentification de l'utilisateur avec "throw new UserNotSignedException()" si celui-ci ne s'est pas encore identifié.