CEF EIDAS v1 pour Spring Security SAML v2 Sample

Dans un précédent post j'expliquais pourquoi un fédérateur standard SAML v2 rencontrait des difficultés avec un noeud eIDAS exposant un Identity Provider (IdP).

Comme je n'aime pas rester sur un échec, j'ai travaillé à la fois le composant eIDAS et SAML v2 pour aboutir à une solution.

Le but de cette manipulation n'est pas de rendre eIDAS totalement compatible avec SAML v2, mais de bien comprendre où réside les quelques spécificités d'eIDAS. Pour cela j'ai utilisé le fédérateur développé par Vladimír Schäfer sur la base du framework Spring Security (Spring Security Saml Sample = ssss). Un des avantages de cette implémentation est l'utilisation de la bibliothèque org.apache.openSaml qui est aussi largement utilisée dans le CED eIDAS, de même que Spring.

La première opération est de rendre les métaDatas eIDAS compatibles avec le standard. Pour cela, il faut exposer les points d'accès de l'IdP. J'ai donc modifié la méthode de génération des metaDatas en reprenant en partie ce que j'ai trouvé dans le projet ssss.

MetadataGenerator.generateIDPSSODescriptor

//binding et endPoint
for(String bind: params.getProtocolBinding()){
  idpSSODescriptor
   .getSingleSignOnServices()
   .add(getSingleSignOnService(params.getEndPoint(),null,bind));
}

/**
* fabrique le endPoint pour le signon
* @param entityBaseURL
* @param entityAlias
* @param binding
* @return 
*/
protected SingleSignOnService getSingleSignOnService(String endpointURL,
   String entityAlias,
   String binding) {
  SAMLObjectBuilder<SingleSignOnService> builder =
    (SAMLObjectBuilder<SingleSignOnService>)
  builderFactory
     .getBuilder(SingleSignOnService.DEFAULT_ELEMENT_NAME);
  SingleSignOnService signonService = builder.buildObject();
  signonService.setLocation(endpointURL);
  signonService.setBinding(binding);
  return signonService;
}

C'est la seule modification que j'ai réalisée côté eIDAS. A partir de là, il est facile de récupérer les informations de l'IdP, qui sont générées dynamiquement par le noeud eIDAS, comme sur cette url.

Le projet ssss permet d'intégrer des métaDatas et aussi de générer des Service Provider (SP). Dans le cas d'eIDAS cette définition doit être particulière. En effet l'entityID doit être une url qui retourne les metaDatas du SP. D'ailleurs c'est mentionné dans le code avec la remarque suivante: 
CAVEAT: the entity descriptor should have its id equal to the url (issuer url)
Heureusement le projet ssss fournit des exemples pour produire cette page (http://countrya.spopoff.com:8080/ssss/metadataeidas). 

La fabrication de l'assertion d'authentification a aussi demandé un travail particulier et j'ai réutilisé une bibliothèque d'eIDAS (saml-engine-eidas.1.0.jar) afin de me simplifier la vie, avec les schémas spécifiques. A cette occasion, on constate le travail important réalisé sur l'encapsulation d'OpenSAML dans eIDAS.

Le retour de la réponse positive de l'IdP dans ssss nécessitait aussi des transformations, car l'IdP ne renvoie qu'un body sans attribut, ce qui rend la sélection du type d'appel sur l'ACS (Assertion Consumer Service) assez délicate. En effet il faut analyser directement le flux (inputStream), ce que l'on ne peut faire qu'une fois.

Au final le cas d'usage est supporté, mais avec une limitation importante: un seul SP doit être présent, ce qui n'est absolument pas la cible du système. En effet au retour de la réponse il n'est pas possible simplement de définir à quel SP elle est destinée. Dans le projet ssss on trouve ce commentaire:
Method tries to load localEntityAlias and localEntityRole from the request path. Path is supposed to be in format:  https(s)://server:port/application/saml/filterName/alias/aliasName/idp|sp?query
Ce qui n'est pas le cas avec l'IdP eIDAS en direct. Cela souligne le fonction du nœud de maintenir toutes les relations entre les SP et des IdP.
Dans l'image ci-dessus, le trait rouge représente le "shunt" que j'ai établit entre l'IdP eIDAS et le SP ssss, alors que justement c'est au connecteur (Node Connector) de faire le joint avec l'IdP (Node Service).

L'application disponible sous ce lien est une mise en oeuvre des éléments précédents. Dans la première page sélectionnez le seul IdP et validez.
Puis suivez la procédure d'authentification FranceConnect (voir lien - validez les attributs et signez vous sur les impôts) et au retour vous serez authentifier:

@sam280 j'ai lu les spécifications eIDAS ;-)

Stéphane POPOFF© sous licence Cecill v2
Comments