Accueil > Non classé > SAML 2 et Liferay – partie 1

SAML 2 et Liferay – partie 1

Cette suite d’articles a pour objectif de présenter l’intégration d’un portail Liferay en tant que fournisseur de services dans une fédération d’identité basé sur SAML 2.0 (authentification et déconnexion unique (SSO et SLO)). Le travail décrit fait partie d’un développement sponsorisé qui a été reversé à la communauté (voir LPS-8427), et devrait être disponible dans la version 6.1 de Liferay, le patch proposé supporte aussi la version 1.1 de SAML, celle-ci étant moins complète que la version 2.0, nous ne nous y intéresserons pas ici.

Dans les premiers articles, nous allons voir comment gérer l’authentification unique, la deuxième partie aura pour sujet la déconnexion centralisée, et la série s’arrêtera avec une apothéose pour la fin de la saison 3 une troisième partie pour traiter d’une pierre deux coups, la correspondance entre les attributs et l’utilisation des métadonnées.

Bien que cette série d’articles soit une application au portail Liferay, elle traite essentiellement de SAML 2.0, et fournit les bases pour l’intégration de ce standard à une application JEE.

Rappel sur les protagonistes

Liferay est un portail JEE top moumoute (où donc ai-je pris ces mauvaises habitudes de langages ???) très abouti, il est compatible avec les spécifications portlets 1.0 et 2.0 (respectivement JSR 168 et JSR 286), et fournit nativement un grand nombre de fonctionnalités (CMS, forum, wiki, blog, etc. …).

SAML (pour Security Assertion Markup Language) est un standard développé par l’OASIS pour la fédération d’identité, basé sur des échanges de messages XML, qui comporte des assertions (les fameux messages XML), des protocoles (autrement dit des échanges de messages, avec format des requêtes et des réponses), des « bindings » (comprendre un mode de transmission des messages) et des « profiles » (scénario s’appuyant sur les éléments précédents pour décrire un cas concret, par exemple l’authentification unique d’un navigateur (Web Browser SSO Profile)).

L’authentification unique

Avant de pouvoir se déconnecter de manière centralisée, il faut déjà s’être connecté, pour cela, regardons plus en détail le « Web Browser SSO Profile ».

Ce scénario comporte 3 acteurs, l’utilisateur (via son navigateur), le fournisseur de services (ou SP, Service Provider, Liferay dans notre cas) et un fournisseur d’identité (ou IdP, Identity Provider, pour mes tests j’avais mis en place SimpleSAMLphp sur un server WAMP) :

Diagramme de séquence du SSO en SAML

  1. L’utilisateur tente d’accéder à une ressource protégée du fournisseur de services sans contexte de sécurité
  2. Le fournisseur de service envoie une demande d’authentification au fournisseur d’identité (message <AuthnRequest>) à travers le navigateur (redirection ou page générant un POST automatique)
  3. Le fournisseur d’identité identifie l’utilisateur (page de connexion ou utilisation d’une session pré-existante)
  4. Le fournisseur d’identité envoie une réponse au fournisseur de services (message <Response>, toujours en passant par le navigateur)
  5. Le fournisseur de service peut se baser sur la réponse du fournisseur d’identité pour créer un contexte de sécurité, et ensuite accorder ou refuser l’accès à la ressource demandée initialement.

Premier pas dans Liferay

Maintenant que l’on a une idée un peu plus claire de ce que l’on souhaite faire, regardons le portail Liferay, et essayons de comprendre comment fonctionnent ses mécanismes d’authentification. Liferay s’intègre déjà avec plusieurs solutions de SSO (dont notamment CAS et OpenSSO (voir aussi OpenAM)) grâce au système d’AutoLogin.

La propriété « auto.login.hooks » du fichier portal.properties (qui peut être surchargé par le fichier portal-ext.properties à la racine du serveur Liferay, ou par plugin hook ou ext) contient une liste de classes qui implémentent l’interface AutoLogin, ces classes sont appelées successivement pour les utilisateurs non connectés jusqu’à ce que l’une d’entre elles renvoie un couple valide identifiant d’utilisateur et mot de passe. Dans ce cas, l’utilisateur sera automatiquement connecté au portail (Non, bien sûr ce n’est pas magique, pour plus de précision jetez un coup d’œil à la classe AutoLoginFilter). C’est aussi ainsi qu’est implémenté le « Remember me » (voir RememberMeAutoLogin qui fonctionne avec un cookie).

Nous allons donc créer une classe SAMLAutoLogin implémentant AutoLogin (comme c’est original…) :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.liferay.portal.security.auth;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SAMLAutoLogin implements AutoLogin {

        @Override
        public String[] login(
                        HttpServletRequest request, HttpServletResponse response)
                throws AutoLoginException {

                // TODO Auto-generated method stub

                return null;
        }

        private static Log _log = LogFactoryUtil.getLog(SAMLAutoLogin.class);

}

Si nous reprenons notre descriptif de l’échange, nous avons presque notre 1), en effet, l’AutoLogin va nous permettre de laisser le soin à Liferay de savoir quand est accédée une ressource protégée. Pour cela, il suffit de constater que lorsque l’utilisateur tente de lire un contenu restreint, le portail affiche le formulaire d’authentification par le biais d’une action Struts d’url « /portal/login », qui redirige vers la portlet Login (je suis sûr que vous ne vous attendiez pas à celle là), qui est une portlet Struts.

Avant de me mettre à répéter Struts sans arrêt, petite piqure de rappel, Liferay est basé sur Struts, et la majorité des portlets natives utilisent le bridge Struts de Liferay. Pour les curieux, ça se passe dans portlet-custom.xml (où se trouve portlet-class), liferay-portlet.xml (voir struts-path), et le classique struts-config.xml. Nous allons donc pouvoir, en testant la présence de « /portal/login/ » dans l’url, savoir que l’utilisateur doit se connecter, vous l’aurez peut-être remarqué, cette astuce fonctionne aussi si l’utilisateur utilise le lien de connexion.

Et là, les petits malins ceux qui sont attentifs se disent : « Lorsqu’on fait du SSO, l’objectif n’est pas de connecter automatiquement l’utilisateur déjà authentifié auprès du fournisseur d’identité dès qu’il arrive sur le site ? Sans qu’il ait besoin de cliquer sur le lien de connexion, ou qu’il ne tente de lire un document privé (qui ne devrait pas être affiché puisqu’il n’est pas connecté). », ce n’est pas faux, mais nous rectifierons plus tard.

Je rappelle (sait-on jamais) que voulant mettre en place une authentification unique, la portlet Login doit être bannie de vos pages…

C’est fini pour aujourd’hui

Nous voilà déjà arrivé à la fin de ce premier article, je vous ai présenté le mécanisme de l’authentification unique dans SAML, et nous avons commencé à l’intégrer dans un portail Liferay en interceptant les utilisateurs non connectés. Dans le prochain article, nous aborderons l’envoi de message via les « bindings ».

A bientôt pour de nouvelles aventures sur le blog Excilys…

 

Share