Entr'ouvert

Projet de fin d'études : Rapport de stage

Université de Technologie de Compiègne

Paul Marillonnet

# Remerciements

# Introduction

# Contexte

## Présentation du sujet de stage

## Présentation d’Entr’ouvert
### Présentation de la structure de SCOP
Entr'ouvert est une SARL (Société A Responsabilité Limitée) de type SCOP.
Historiquement, cet acronyme signifie Société Coopérative Ouvrière de Production. Créé en 1947, ce statut juridique d'entreprise est maintenant défini par les termes de Société COopérative et Participative.
Créée en 2002, la coopérative Entr'ouvert comporte maintenant 10 associés.

### Entr'ouvert en tant que SCOP
Les membres d'Entr'ouvert ont souhaité aller plus loin dans le principe coopératif et ouvert, que les contraintes légales de la structure organisationnelle et juridique d'une SCOP. Cette extension du statut est notamment présent sous différents aspects :
* Participations //TODO alignée pour tout le monde.
    Pas définie par le poste occupé, seulement par le nombre d'heures travaillées
* La rémunération des associés est la même pour tout le monde. Un développeur touche ainsi le même salaire qu'un employé.
* Les décisions importantes pour la coopérative sont prises par vote (chaque collaborateur comptant pour une voix)
* La gérance de la coopérative est assurée à tour de rôle, par changement de gérant tous les trois ans.
* Les associés détiennent au total 100% des parts de la coopérative. Chacun des 10 associés détient 1/10 des parts de la coopérative.
* L'espace de travail dans les locaux parisiens est de type "collaboratif" : il s'agit espace ouvert (*open space*), pas de places attribuées
* Le développement des outils a recours à un système de revue de code (*code review)* par soumission de patches sur la plateforme Redmine de l'entreprise.
* La société ne comporte pas de capital à proprement parler, seulement une somme symbolique (800€ par coopérateur, soit 8000€ actuellement).

### EO et les collectivités
Dynamique de travail créée par la collaboration avec les collectivités
Considérations en vrac :
Rémunérations débloquées plus tardivement (notion de *budget* pour les collectivités diffère du portefeuille d'une entreprise)

### En conclusion
Indicateur rassurant : peu de *turn-over* dans l'équipe


## La distribution de logiciel libre
Les outils Web  distribués par Entr'ouvert proposent des solutions aux problématiques de l'e-Administration d'une part (environ 70% de l'activité de l'entreprise) et de Gestion des Identités numériques (GI) d'autre part (30% de l'activité).
L'outil Web utilisé pour le développement est Django, il s'agit d'un framework Web écrit en Python (2.7 et 3.6).
Django suit le paradigme DRY (*Don't Repeat Yourself*), des fonctionnalités de modularisation sont fournies par défaut avec l'outil, afin de factoriser au maximum les briques logicielles développées.
Contourne le motif usuel MVC (*Model, View, Controller*, par exemple celui de JEE), pour proposer un modèle plus léger, dénommé MVT (pour *Model, View, Template*).
L'idée-même de capitalisation prend un autre sens dans le cadre d'un SCOP de logiciel libre, la capitalisation valorisée ici est celle des connaissances et de l'expertise des membres de l'équipe plutôt que la thésaurisation d'un capital financier.

//Bi'Joe / Bistrot pour la gestion des demandes client

//EN COURS
Entr'ouvert est aussi membre du réseau Libre Entreprise (avec d'autres société libristes telles que Easter-Eggs ou Code Lutin).
Ce réseau a pour objectif de promouvoir un ensemble de valeurs telles que la démocratie d'entreprise, la transparence de l'information (qu'elle soit interne ou externe à l'entreprise), un nombre de salariés raisonnable//, et l'indépendance, notamment vis-à-vis des financements extérieurs. //TODO à vérifier, il semblerait que ce ne soit plus le cas.

//TODO démocratie d'entreprise : définition
Le terme de démocratie d'entreprise implique un certains nombres de conventions concernant les prises de décision dans l'entreprise.
Les décisions se font ainsi par vote, chaque salarié de l'entreprise représentant une et une seule voix.
Par exemple, le salarié occupant le poste de gérant, en tant que représentant légal de l'entreprise, est élu par vote de façon périodique (tous les trois ans pour Entr'ouvert).

Enfin, 70% des bénéfices de la boîte sont répartis de façon équilibrée entre chacun des coopérateurs.

#### La licence utilisée
Il faut tout d'abord émettre certaines réserves concernant la licence la plus utilisée dans le monde du libre, à savoir la General Public Licence (en version 2 ou 3).
Créée par Richard Stallman en tant que fondement de la Free Software Initiative, cette licence est particulièrement adaptée aux applications natives (c'est-à-dire dont le programme binaire tourne sur la machine client). En effet, la licence GPL se propage //TODO
Outils Web justifient une distribution du code sous licence AGPL.

//HS :
Autre particularité : fuir le modèle de développement 1 nouveau client = 1 fork pour chacun des outils distribués
Celui induirait un coup de maintenance déraisonné
Ici : une unique branche *master* pour chacun des dépôts de code.

Utilisation de logiciels libres seulement
Promotion de logiciels libres
Ex: besoins de localisation spatiales pour certaines communes ->  plutôt que l'API Google Maps, hébergement d'un serveur Open Street Maps
Cela pousse à une meilleure connaissance des outils
Héberger complètement un outil : maîtrise technique supérieure qu'un simple exploitation d'interface d'un outil fermé.

//Vision orientée humain : évacuer tous les cas standards pour pouvoir consacrer plus de temps aux dossiers inhabituels

## Le travail avec les collectivités

## La gestion des projets EO

### Git/gitolite
git est le système de contrôle de version créé pour le développement du noyau Linux. Il propose un modèle de données plus performant en espace mémoire et en vitesse d'exécution, par rapport à ses prédécesseurs (SVN notamment).

Avantage certain sur svn au niveau du stockage des blobs : là où les fusions de branches (*merge*) peuvent prendre des heures avec svn, ce type d'opération est presque instantané avec git. Chaque version d'un fichier est stockée de façon complète, contrairement à SVN qui opère sur des diffs.

Gitolite est une implémentation libre d'un serveur git, c'est-à-dire permettant d'héberger des dépôts git, et de mettre en place une politique d'accès à ces dépôts. Cet outil, écrit principalement en langage Perl par Sitaram Chamarty, est distribué sous licence GPLv2.

Il est utilisé par différents acteurs du logiciel libre tels que les développeurs du noyau Linux (kernel.org) et le projet Fedora (distribution Linux communautaire et soutenue par RedHat).

La listes des dépôts d'Entr'ouvert est consultable sur https://git.entrouvert.org

### Redmine

### Bistro

## Description de mon poste/intégration à l'équipe/organisation du travail

# Cas d’usage

## Approche fonctionnelle du problème
 
## Synthèse des différentes technologies disponibles

//Une seule page maxi

# État de l’art de la gestion des identités numériques

## Les solutions libres pour la synchronisation et l’approvisionnement des référentiels d’identités numériques
### Authentic 2
La brique logicielle Authentic, actuellement dans sa second version, écrite en Python2 à l'aide du *framework* Django, permet d'assurer toutes les fonctionnalités liées à l'authentification des usagers dans le cadre d'une problématique de gestion des identités. Cette solution peut ainsi être déployée en tant que fournisseur d'identité dans la solution Publik, développée par Entr'ouvert pour des besoins de GRC (Gestion des Relations Citoyen).
TODO Installation et déploiement en local
TODO Ecriture d'un dummy SP pour tester Authentic ??

TODO Expliquer les particularités de la licence GNU Affero GPL (APGL) :
- l'utilisation du code pour des applications Web déployées est pris en compte dans le caractère transitif ("contaminant") de la licence.
TODO Quel intérêt de licencier la documentation sous Creative Commons ?
#### Documentation
Comprendre l'interaction avec Lasso pour le support SAMLv2

One-time password support ?

Sphinx, génération de la doc
Cf structure des fichiers rst

##### Administration
L'administration d'Authentic 2 se fait de façon classique, à l'aide du module d'administration de Django, lequel propose une interface graphique disponible à la page `/admin/` du site.
Il faudra cependant veiller à créer un *superuser* lors de l'initialisation de la base.

Le contrôle d'accès aux ressources Authentic se fait par recours à deux politiques globales appelées 'Default' et 'All'. //TODO reformuler
Le mécanisme de politiques d'accès géré par Authentic est extensible : l'administrateur du service peut en définir, en plus des politiques 'Default' et ' All'.

Le niveau de granularité de ces politiques est l'objet : à chaque objet il est possible d'attribuer une politique d'accès. // Au sens de la POO ?

//TODO Pourquoi est-il nécessaire d'appliquer la politique 'All' sur tous les objets ? Quel(s) problème(s) si on ne le fait pas ?

##### Gestion des attributs SAML2
Il s'agit ici de configurer une politique de gestion des attributs envoyés dans les réponses de succès d'authentification envoyées par Authentic 2 aux SPs.

L'utilisation des attributs SAML2 dans les réponses Authentic varie en fonction des cas d'utilisation, Authentic peut ou on être configuré en tant que SP SAML2.

//TODO Relire `attribute_management.rst`
Ligne 207 : une associe une politique à un SP
Cas particulier du SSO
Revoir scenario d'utilisation avec mire de connexion

##### Authentification
Avec LDAP ou laissée à PAM
Rappel: la configuration de PAM sous UNIX se fait à l'aide des fichiers situés dans `/etc/pam.d`

Configuration de la variable `AUTHENTICATION_BACKEND` du `settings.py` des sources Django.

##### SAML2 et croisement des données entre différents compte
Cette possibilité de croisement des données entres les différents comptes liéss à une même identité est au coeur de la fédération d'identité (On parle de *account linking consent*).

C'est le fournisseur d'identité (IdP) qui gère le consentement des utilisateurs à la liaison de leurs différents comptes.
Les données ne sont pas forcément croisées, il peut simplement s'agir de la mise en place d'un mécanisme de SSO.

Dans ce cas, le message SAML AuthnRequest contient un champ indiquant le choix de l'utilisateur quant au croisement des ses comptes.

Si l'IdP manipule des identifiants opaques (*transient*), alors le consentement de l'utilisateur au croisement des comptes n'est pas nécessaire. //TODO à vérifier

On notera aussi que le fournisseur de service (SP) est en droit de refuser un SSO valide si le consentement de l'utilisateur n'a pas été recueilli. //S'agit-il ici de Authentic en tant que SP ?

Il faut aussi gérer le consentement à la redirection d'attributs (*attribute forwarding consent*).
Dans Authentic 2, cette politique de gestion consiste en un choix parmi trois possibilités :
* Ne pas demander à l'utilisateur son accord
* Recueillir un consentement global pour l'ensemble des attributs ("Tout ou rien")
* Permettre à l'utilisateur de choisir, attribut par attribut, ceux qui peuvent être redirigés

#### authentic2-ctl
installation par pip en local
pip install ./
Outil d'administration en ligne de commande

#### Installation
* AttributeError: 'module' object has no attribute 'PassThroughManager'
	quand : utilisation de authentic2-ctl
	pourquoi : incompatibilité sur les versions récentes du module django-model-utils
	solution :  rétrograder le module django-model-utils à une version <= 2.3

##### virtualenv Python
Le mécanisme de création d'environnements virtuels sous Python permet de faire cohabiter sur un même système des installations disparates. Par exemple, un même module Python peut être présent en différentes versions tant que ces versions se situent dans des environnements virtuels différents.

Les répertoires d'installation des modules Python dans le cadre d'un virtualenv sont seulement locaux à l'environnement créé.

##### Troubleshooting
-


##### Utilisation des *tenants* du SGBDR

### Apache Syncope
Syncope est le projet d'outil de gestion des identités numériques de la fondation Apache.
Il est écrit en J2E et est distribué sous licence Apache.

L'identité numérique consiste en un ensemble de demandes qu'un sujet numérique peut effectuer à propos de lui-même.

Notion de cycle de vie des données d'identité telle que définie par le projet, à travers le *provisioning* et le *deprovisioning*.

//TODO Inclure image du projet Apache Syncope


#### Tuto officiel (*Getting Started*)
La problématique centrale de GI telle que le conçoit Syncope est
"Qui a accès à Quoi, Quand, Comment et Pourquoi ?"

Trois types d'objet sont définis par Apache Syncope : les utilisateurs (*Users*), les groupes (*Groups*), et d'autres objets n'appartenant pas à ces deux premières classes, par l'introduction des objets de type *Any*.

Plusieurs techno différentes sont nécessaires dans un scenario de gestion des identités avec Syncope.
Comme la plupart des IdM, Syncope nécessite l'utilisation d'un outil de stockage des identités (*Identity Store*). Il peut s'agir d'un SGDBR, d'un annuaire LDAP ou même d'un fichier "à plat".
Syncope prend en charge les fonctionnalités d'approvisionnement (*Provisioning engine*) et de gestion d'accès (*Access Manager*).

Le moteur d'approvisionnement, fourni par Syncope, est responsable des fonctionnalités de synchronisation des différentes bases de référentiels d'identité, avec toutes les problématiques de compatibilité (formats, modèles, sémantiques) qui en résultent.

Le gestionnaire d'accès se charge de l'authentification, des autorisations et de la fédération des identités fournies aux différents services de l'architecture.

Cf `syncope_architecture.png`. Description de la pile logicielle usuelle d'une appli Web utilisant Syncope.
Syncope -> partie 'Core', du front au back en assurant aussi la sécurité.

//TODO CF Activiti BPM

La persistence est assurée par JPA, et les propriétés ACID du stockage sont prises en charge par le système transactionnel du framework Spring.

Connecteurs : ConnId pour l'implémentation des connecteurs
Post SUN ICF (Identity Connector Framework)

Penser à installer les trois paquets Debian (la base, 'console',  et 'enduser')

Installation de la GUI en client lourd ? Vraiment nécessaire ?

`http://localhost:8080/syncope-console/login?1`

default credentials : admin / password

TODO Tuto Apache Maven
#### Apache Maven
Outil de gestion de projet (au sens de gestion technique: résolution des dépendances, automatisation du build, packaging, génération de la doc, etc)

`JAVA_HOME` utilisé /usr/lib/jvm/java-1.8.0-openjdk-amd64
Faire les modification dans /etc/profile
Fichier lu au démarrage d'un login shell

Installation :
Fichier binaire directement disponible
Penser à rajouter le répertoire d'installation de Maven au $PATH

Il convient maintenant de configurer proprement Maven

`# OpenJDK environment configuration`
`export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-amd64"`
`export PATH=$JAVA_HOME/bin:$PATH`
`# Add Maven to the binary search path`
`export PATH=/opt/apache-maven-3.3.9/bin:$PATH`
`export MAVEN_OPTS="-XMs256m -Xmx512m"`
Dernière options pour définir l'utilisation RAM de la VM Java

TODO en quoi Maven va plus loin que Ant pour ce qui est du build ?

#### Lancement de Syncope
Création du projet à l'aide des *archetypes* Maven.

`/opt/apache-maven-3.3.9/bin/mvn archetype:generate \`
`    -DarchetypeGroupId=org.apache.syncope \`
`    -DarchetypeArtifactId=syncope-archetype \`
`    -DarchetypeRepository=http://repo1.maven.org/maven2 \`
`    -DarchetypeVersion=2.0.2`

Manipulation de fichiers POM

`paul@spare:~/Documents/syncope.test/synctest$ find ./ -name '*.war'`
`./core/target/syncope.war`
`./console/target/syncope-console.war`
`./enduser/target/syncope-enduser.war`

Utilisation des profils Maven (option CLI '-P'), par exemple pour le mode *embedded* pour la partir enduser de Syncope


Première constatation : niveau performances de l'interface Web d'administration, c'est vraiment trop lent.
Pb inhérent à Java ?

Système de contrôle d'accès lui aussi défini par des rôles
On parle aussi de relations (*Relationships*) pour définir les ressources auxquelles un utilisateur a accès.
Ces ressources peuvent être internes ou non au groupe.

Pb : inutilisable en l'état : Unknown [ActivitiObjectNotFoundException: execution 10 doesn't exist]
Exception non capturée dans le code
Impossible d'utiliser l'interface d'administration

TODO : Troobleshoot + étudier cas de synchro de réfs d'identités hétérogènes.

Aller investiguer dans http://localhost:9080/syncope/db.jsp pour comprendre le modèle de stockage des identités mis en place par syncope


### evolveum midPoint
Projet écrit un Java, difficilement interfaçable avec les outils entr'ouvert.
Lourd (projet git de taille 230Mo)
Multifonctions :
- Automatisation de la création (*provisioning*) et suppression (*deprovisioning*) des référentiels d'identité gérés.
- synchro et gestion des conflits (*reconciliation*)
- Automatisation des processus d'acceptation des requêtes au référentiel d'identité
- Contrôle d'accès défini par les rôles (*Role-based access control* ou RBAC)
- Outils de monitoring
- utilisation de connecteurs standards pour interfacer les SP en tant qu'IDP
TODO Parcourir sources, identifier les modules correspondant aux fonctions proposées

Installation à partir des sources, à l'aide de Maven

Déploiement d'un WAR de façon automatique avec tomcat ?
Ne fonctionne pas pour l'instant

Problème de taille de mémoire allouée à la JVM ?
Réessayer avec le manager GUI de tomcat (`/manager`)

Résolution : définition correcte du `MIDPOINT_HOME` dans `$CATALINA_HOME/setenv.sh` (script à créer)

### Linagora LinID
Leur serveur ruby on rails (linid.org) est par terre pour le moment.

### ForgeRock OpenIDM
Pour l'instant, impossible de le faire fonctionner, documentation trop light.

Lecture des sources et de la documentation
Projet Java open source, dépôt git

Synchronisation de référentiels d'identités hétérogènes, par exemple Active Directory (Microsoft), OpenLDAP ou encore OpenDJ
-> Les schémas ne sont pas les mêmes.

Mécanismes de correction des erreurs dans le référentiel, y compris lors de la phase de synchronisation
Mise à disposition de 'nightly builds' (~versions Beta)

Pré-requis pour l'installation
Windows ou Linux
Java  7 ou 8 (JRE ou JDK)

#### Processus de synchronisation des référentiels d'identité
La documentation disponible sur le site de ForgeRock propose un exemple de synchronisation entre deux référentiels de natures différentes. Dans le scénario proposé ici, il s'agit d'une synchronisation 'à sens unique' (*One Way Synchronisation*) entre deux services d'une même entreprise, à savoir Ressources Humaines et Pôle technique.
Le premier des deux services stocke ses données d'identités dans un fichier csv tandis que le second a recours à un fichier XML.
Le processus de synchronisation ne peut être effectué de façon automatisée sans avoir été configuré auparavant.
En effet, il n'est en général pas possible d'établir un mappping entre un fichier plat de type CSV et un fichier structuré de façon arborescente tel que XML sans avoir défini des règles d'appareillement des données d'identités.

L'exemple décrit ici propose un fichier de configuration d'appareillement des entrées du premier référentiel vers celles du second.

Fichier sync.json : liste de dictionnaires contenant deux entrées seulement
'source' et 'target'
```
"properties" : [
                {
                    "source" : "Name",
                    "target" : "name"
                },
                {
                    "source" : "lastName",
                    "target" : "lastname"
                },
                {
                    "source" : "firstName",
                    "target" : "firstname"
                },
                {
                    "source" : "email",
                    "target" : "email"
                },
                {
...
}
```

Ce fichier JSON permet une synchronisation à sens unique, c'est à dire d'un référentiel A vers un référentiel B. Il s'agit d'un simple mapping d'attributs, où si `properties(source) == attrA_i`, pour `i` quelconque, alors `properties(target) == attrB_i`.

On notera par ailleurs que le processus de synchronisation peut être effectué l'aide du serveur HTTP(S) proposé par OpenIDM, qui fournit une interface Web pour la gestion des identités.

#### Business processes, workflows

OpenIDM propose par ailleurs des fonctionnalités répondant à des besoins secondaires de la gestion des identités. Ainsi, tout comme pour Authentic2, l'ajout d'un compte utilisateur n'est pas forcément initié par l'administrateur du gestionnaire d'identités, mais par l'utilisateur lui-même. On parle d'auto-enregistrement (ou *self-registration*).

La certification des comptes utilisateur (*account certification*) est aussi gérée par ce genre d'outil.

Plus généralement, on associe à ce genre de fonctionnalités des objectifs de gestion de *business processes* (littéralement `processus métier`), ou encore de *workflow*.

Il est possible de nuancer ces deux termes. Un *business process* désigne tout ensemble de tâches dont la réalisation conditionne un objectif métier (réalisation d'un produit, mise en place d'un service, etc). 
Un *workflow* désigne tout procédé faisant intervenir un agent tout en ayant aussi recours à des tâches automatisées.

Des solutions libres sont disponibles pour répondre aux besoins de gestion des *workflows* et des processus métier.

Tandis que la solution Publik intègre l'outil de gestion des workflows w.c.s., OpenIDM intègre quant à lui la solution libre Activiti.
Distribué sous licence Apache 2.0 par Alfresco, Activiti suit la norme BPMN (Business Process Model and Notation) 2.0 pour la formalisation des processus métier.

Cette norme propose ainsi une description intelligible des langages d'exécution des processus métier, tels que WSBPEL (Web Services Business Process Execution Language).
Cette formalisation est appuyée par la spécification de trois types de diagrammes, à savoir les diagrammes de collaboration, les diagrammes de processus et les diagrammes de 'chorégraphie' (*choreograpjhy diagram*).

Cette norme BPMN 2.0 a recours à plusieurs standards descriptifs pour la normalisation de chacun des trois types d'entités manipulées :
- la définition des types de données est réalisée à l'aide de XML Schema
- l'API des services Web est décrite par WSDL
- le langage d'accès aux données est XPath

Les schémas XMI et XSD du standard BPMN 20 sont disponibles à l'adresse :
http://www.omg.org/spec/BPMN/2.0/

// TODO? revue des différents piliers de la spec BPMN, petite synthèse sur 2, 3 pages ?

#### Fonctionnalités annexes

Il est possible de dégager un ensemble de fonctionnalités utiles dans la cadre de la gestion des identités (même si elles ne sont pas directement liées aux thématiques de la synchronisation et de l'approvisionnement). OpenIDM propose à l'admin GI de mettre en place une politique de sécurité concernant les mots de passe des utilisateurs. La politique de sécurité des mots de passe est configurable à l'aide de plusieurs paramètres. (Motifs interdits dans les passwords, date de validité, gestion d'un historique pour éviter la réutilisation des mots de passe).
//TODO si nécessaire, cf chapitre 4.5 'Managing passwords'

//Notion de rôle, en tant que scénario utilisateur TODIG

#### Connecteur fournis avec l'application
L'outil OpenIDM propose un panel de connecteurs pour s'interfacer à différents outils permettant le référencement des identités numériques :
- Google WebApps //TODO? Quelles applis en particulier ? Aller chercher ses contacts mails par exemple
- Les outils CRM de Salesforce
- LDAPv3
- CSV
- SGBDR (MySQL, postgres)

Plus intéressant, OpenIDM propose une fonctionnalité d'écriture de connecteurs à l'aide de Groovy (cf *Groovy connector framework*). Des scripts Groovy peuvent alors s'exécuter sur OpenIDM pour l'interface avec potentiellement tout type de connecteur.
Concrêtement, l'interface des connecteurs scriptés est figée, il s'agit d'un ensemble de scripts Groovy, chacun ayant pour but de remplir l'un des rôles nécessaires à la synchronisation.

Prenons par exemple le script du connecteur Microsoft Azure destiné à remplir la fonction de création d'un utilisateur :
//TODO: en annexes !
Fichier `openidm-public.git:openidm-zip/src/main/resources/samples/scriptedazure/tools/scripts/CreateScript.groovy`
``` Java
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
  * Copyright (c) 2014 ForgeRock AS. All Rights Reserved
  *
  * The contents of this file are subject to the terms
  * of the Common Development and Distribution License
  * (the License). You may not use this file except in
  * compliance with the License.
  *
  * You can obtain a copy of the License at
  * http://forgerock.org/license/CDDLv1.0.html
  * See the License for the specific language governing
  * permission and limitations under the License.
  *
  * When distributing Covered Code, include this CDDL
  * Header Notice in each file and include the License file
  * at http://forgerock.org/license/CDDLv1.0.html
  * If applicable, add the following below the CDDL Header,
  * with the fields enclosed by brackets [] replaced by
  * your own identifying information:
  * "Portions Copyrighted [year] [name of copyright owner]"
  */
 
 import AzureADOAuth2HttpClientFactory
 import org.apache.commons.io.IOUtils
 import org.apache.olingo.client.api.communication.ODataClientErrorException
 import org.apache.olingo.client.api.v3.EdmEnabledODataClient
 import org.apache.olingo.commons.api.domain.CommonODataEntity
 import org.apache.olingo.commons.api.domain.v3.ODataObjectFactory
 import org.apache.olingo.commons.api.format.ODataFormat
 import org.forgerock.openicf.misc.scriptedcommon.OperationType
 import org.forgerock.openicf.misc.scriptedcommon.ScriptedConfiguration
 import org.identityconnectors.common.logging.Log
 import org.identityconnectors.framework.common.objects.Attribute
 import org.identityconnectors.framework.common.objects.AttributesAccessor
 import org.identityconnectors.framework.common.objects.ObjectClass
 import org.identityconnectors.framework.common.objects.OperationOptions
 
 def operation = operation as OperationType
 def createAttributes = new AttributesAccessor(attributes as Set<Attribute>)
 def configuration = configuration as ScriptedConfiguration
 def client = configuration.propertyBag.get("ODataClient") as EdmEnabledODataClient
 
 def name = id as String
 def log = log as Log
 def objectClass = objectClass as ObjectClass
 def options = options as OperationOptions
 
 
 def entityType = ODataUtils.getEdmEntityType(client.cachedEdm, objectClass)
 
 if (null != entityType) {
 
     ODataObjectFactory factory = client.getObjectFactory();
     CommonODataEntity entity = factory.newEntity(entityType.annotationsTargetFQN)
 
     entityType.properties.each { key, value ->
         Attribute attribute = createAttributes.find(key as String)
 
         if (null != attribute) {
             entity.getProperties().add(ODataUtils.valueBuild(factory, value, attribute.value))
         }
     }
 
     try {
         def request = client.CUDRequestFactory.getEntityCreateRequest(ODataUtils.buildEntityURI(client.newURIBuilder(), entityType, null), entity)
 
         if (log.ok) {
             def content = IOUtils.toString(client.getWriter().writeEntity(entity, ODataFormat.fromString(request.getContentType())))
             log.ok("Create Request: {0}", content)
         }
 
         def response = AzureADOAuth2HttpClientFactory.execute(request)
         return ODataUtils.getUid(entityType, response.body)
     } catch (ODataClientErrorException e) {
         throw ODataUtils.adapt(e)
     }
 
 } else {
     throw new UnsupportedOperationException(operation.name() + " operation of type:" +
             objectClass.objectClassValue + " is not supported.")
 }
```

Dans le cadre de la démarche comparative de cette étude, nous pouvons d'ores et déjà émettre une certaine critique à l'égard de cette fonctionnalité.
En dépit des avantages pronés par la fondation Apache concernant Groovy, on constate à première vue que ce langage de script dérivé de Java est moins lisible et intuitif que des équivalents en termes de langages de script utilisés dans le Web en général (Python, Ruby, ECMAScript).
Le code logique l'emporte sur le code métier (*Factories, CreateRequests, Writers*) et rend l'ensemble du code difficile à comprendre.
On pourra aussi sans doute reprocher aux librairies et modules utilisés une trop grande imbrication des objets entre eux qui n'encourage pas non plus à la facilité de lecture du code. En témoigne la ligne :

``` Java
def content = IOUtils.toString(client.getWriter().writeEntity(entity, ODataFormat.fromString(request.getContentType())))
```

#### Gestion/resolution des conflits de synchronisation
Le mécanisme automatisé de synchronisation mis à disposition par OpenIDM propose des fonctionnalités de résolution des incohérences de données d'identités entre les différents référentiels pris en charge.
La documentation écrite en anglais parle de *reconciliation*.

La réconciliation est la phase cruciale de la synchronisation puisque c'est elle qui va déterminer la façon dont les changements de l'un des référentiels sont répercutés sur les autres référentiels.
La politique de résolution des conflits de synchro entre deux (ou plus de deux) référentiels d'identités est configurable par l'administrateur de OpenIDM
La documentation OpenIDM fournit un exemple détaille dans le cas d'un référentiel interne à OpenIDM et d'un référentiel externe OpenLDAP (ici OpenDJ).

Fichier de conf de la base interne : `repo.*.db`
Utilisation du framework de connecteur OpenICF.
Paramètre à fournir pour la synchro
```
"baseContextsToSynchronize"; "attributesToSynchronize"; "objectClassesToSynchronize"; "modifiersNamesToFilterOut"
```

La configuration peut être encore plus poussée, avec un paramétrage par classe d'objet et même par attribut du référentiel externe
A recours à JSON Schema

Le mapping, une fois de plus :
```
{
    "mappings" : [
        {
            "name" : "systemLdapAccounts_managedUser",
            "source" : "system/ldap/account",
            "target" : "managed/user",
            "properties" : [
                { "source" : "uid", "target" : "uid" },
                { "source" : "sn", "target" : "lastname" },
                { "source" : "givenName", "target" : "firstname" },
                { "source" : "mail", "target" : "email" },
                { "source" : "description", "target" : "description" }
            ],
            "policies" : [
                { "situation" : "CONFIRMED", "action" : "UPDATE" },
                { "situation" : "FOUND", "action" : "IGNORE" },
                { "situation" : "ABSENT", "action" : "CREATE" },
                { "situation" : "AMBIGUOUS", "action" : "IGNORE" },
                { "situation" : "MISSING", "action" : "IGNORE" },
                { "situation" : "UNQUALIFIED", "action" : "IGNORE" },
                { "situation" : "UNASSIGNED", "action" : "IGNORE" }
            ]
        }
```
Intéressant ici : notion de politique, avec les actions à effectuer par OpenIDM dans chacunes des *situations*.

Déclenchement de la synchro
- planifiée de façon régulière (façon 'cronjob')
- TODO API REST

#### OpenIDM Sample Files
Description de cas d'utilisation dans des fichiers d'échantillon. Plusieurs cas décrit : //TODIG
- Gestion de résolution de conflit sur des données utilisateurs stockées sur un fichier XML
- Scripts de génération des messages de logs de l'application (y compris messages de debug)
- Resolution asynchrone de conflits à l'aide de *workflows*

#### API RESTful
TODO

#### Artefacts (*Artifacts*)
TODO
"Artifacts handled by OpenIDM are Java object representations of the JavaScript object model as defined by JSON."
Comprendre le fonctionnement des artefacts

BIG TODO : faire tourner l'appli...


# Prise en main des technologies

## Django
TODO Se documenter sur les templates (modèle MVT)
Expliquer philosophie DRY (*Don't Repeat Yourself*)
### Principes généraux
#### Vues

##### Class-Based Views (CBV)
Nouvelle façon d'écrire des vues
Repose sur la définition d'une classe contenant les attributs nécessaires à la construction de la vue et la définition de méthodes correspondant aux requêtes http vers la vue

Les *mixins* propose, par l'utilisation de l'héritage multiple, un mécanisme voué à éviter la duplication du code dans les CBV.

##### Decorators
La mise en place du POC a nécessité l'utilisation de décorateurs de vue. Ce mécanisme propre à Django permet de restreindre l'affichage d'une vue sous certaines conditions.
Des décorateurs sont proposés par défaut dans Django. Ils commencent par `@` et précédent la définition d'une vue dans les sources de l'application. Par exemple:
`@csrf_exempt`
`def index(request):`
`    <view logic>`
`    return wcs_submit(data)`

Le décorateur `@csrf_exempt` est de type permissif : il stipule que le client (par exemple un navigateur) n'a pas besoin de fournir un jeton CSRF (*csrf token*) pour pouvoir accéder  à la vue.

Au contraire, des décorateurs tels que `@login_required` ou `@require_http_methods` peuvent être de type restrictif.

Bien que Django fournisse des décorateurs par défaut, ce framework permet aux développeurs de définir les leurs. Un décorateur est une double définition de deux fonctions imbriquées - l'un des deux fonctions devant renvoyer en argument la seconde. Par exemple, nous pouvons définir un décorateur interdisant l'affichage de la vue si le dernier utilisateur connecté possède déjà un compte renseigné dans le LDAP:

`def user_not_in_ldap(function):`
`    def wrapped(request, *args, **kwargs):`
`        user_data = saml_collect_data()`
`        if ldap_is_in_directory(user_data):`
`            raise PermissionDenied`
`        else:`
`            return function(request, *args, **kwargs)`
`    return wrapped`


##### URIs
APPEND_SLASH ?
"Adding slash to: '/login'"

#### Modèles
Les modèles Django standardisent l'utilisation des objets dans l'application web.
Ils reprennent les mécanismes de POO proposés par Python, pour faciliter la mise en place de l'appli Web, et plus particulièrement les mécanismes ORM (*Object-Relational Mapping*).

La définition de modèles spécifiques à l'application se fait dans le fichier `models.py`. L'utilitaire Django `manage.py` permet la migration en base de données, c'est-à-dire la création des tables associées aux classes définies dans l'appli. Prenons l'exemple du modèle TODOTODOTODO

#### Templates
Langage procédural propre à django à l'intérieur des templates.
Il s'agit d'un langage à syntaxe restreintes, permettant d'effectuer des operations d'affichage et des opérations fonctionnelles et logiques simples avant génération de la page html.

Les templates Django sont un outil plus léger et plus simple d'utilisation que JSP, son équivalent J2E.

Prenons l'exemple d'un template utilisé pour l'application POC :
Fichier login.html :
`{% extends "manager_base.html" %}`
`{% load i18n %}`
`{% block content %}`
`<form method="post">`
`{% csrf_token %}`
`{{ form.as_p }}`
`<input type="submit" value="{% trans 'Log in' %}" />`
`</form>`
`{% endblock %}`

On remarque par exemple le *one-liner* `{{ form.as_p }}` permettant l'affichage d'un formulaire html à partir des différents attributs d'un objet Django de la classe `Form.forms`.
L'ajout du jeton CSRF en tant que balise cachée (*hidden tag*) du formulaire se fait par l'instruction `{% csrf_token %}`

Le template est ensuite traité par l'instruction `render` dans la vue associée, pour aboutir à la génération d'une page html présentée au client (traitement côté serveur, au même titre que les JSP).

Finalement, suivant le principe DRY propre à Django, les templates s'appeler les uns les autres à l'aide de la directive `extends`.
#### TemplateResponse
Dynamise la phase de création de la réponse HTTP après exécution de la vue associée. Fonctionnalité impossible à réaliser à l'aide de simples objets HttpResponse.

La manipulation des mixins se fait à l'aide de l'objet SingleObjectMixin et de SingleObjectTemplateResponseMixin.
TODO Si mixin associé à une ListView, alors MultipleObjectMixin.

### Remarques
L'interface Web d'administration et le compte *superuser* ne sont pas activés par défaut.
Page `/admin` pour la gestion des webapps.
Opérations CRUD : Create, Read, Update, Delete

La GUI est générée automatiquement en fonction des modèles de donnée de l'application, pourvu que ceux-ci aient été enregistrés au préalable (méthode `admin.site.register()`)

Champs `list_display`, `list_filter`, `date_hierarchy`, `ordering` et `search_fields` de la classe `admin.ModelAdmin`

Classe Q : requêtes avancées -> à lire
Appli ContentType pour les relations génériques

*template context processors*

*custom tags* utilisant la fonction *render*

django.db.models.signals

django.contrib.auth.models.User

#### Ecriture des tests
base de tests (préfixe test_)

notion de fixture : données qui seront importées dans la base de données

##### Django TestCases

##### tox

#### Packaging and releasing

sdist ?

##### Le format *egg*
Il s'agit de l'une des solutions disponibles dans Python pour la packaging des applications Python.
Création d'un dossier .egg-info, et d'un fichier d'archive egg

TODO format egg

##### Python Wheel
extension .whl
aussi compressée au format zip
python wheel

dist-info
METADATA
WHEEL
RECORD "enregistrement" de tous les fichiers et de leurs valeurs de hachage

respecte les spécs PEP376 ? pas à 100%
TODO PEP426

##### Le packaging dans Django
setup.py dans django
syntaxe spécifique de renseignement des méta-données dans pour le projet
Django utilise setuptools
fonction setup(...) pour fournir les différentes méta-données
name, version, packages, include_package_data
license,...

mais surtout: classifiers qui permettent de catégoriser l'application en la classant selon un certains nombre de critères (framework, OS hôte, type d'utilisateur visé, langage utilisé, ...)

#### Code de conduite PyPA ?

## w.c.s / Passerelle
L'outil de gestion de formulaires et de workflow a été utilisé dans la mise en place du POC. L'utilisation du protocole https nécessite d'installer modules Apache ssl (l'une des implémentations openssl ou gnutls), scgi, rewrite.

La gestion de l'authentification dans w.c.s. nécessite la définition d'une méthode de signature. La méthode retenue est
```
BASE64(HMAC-HASH(query_string+'algo=HASH&timestamp=' + timestamp + '&orig=" + orig, clé))
```

BASE64 désigne l'encodage en base 64 (i.e. sur 6 octets) de la signature. Par ailleurs, HMAC-HASH est la fonction de hachage utilisée pour signer les messages. Spécifique à la génération de code d'authentification, cette méthode repose sur l'utilisation d'une clé secrète.


Retrait de l'exception enpêchant l'absence de signature dans les appels à l'API -> Commentée
Pas pertinent pour l'instant dans le cadre du POC


Gestion locale de l'authent, pas de recours à un IdP pour w.c.s. : pas nécessaire dans le cadre du POC ?
Se connecter en tant qu'admin pour pouvoir accéder aux interfaces de gestion des formulaires en attente d'acceptation

Quel algo de hachage pour le champ password en wcs ?

### API ReST
L'API proposée par l'outil w.c.s. suit les conventions REST telles que définies par Roy Fielding au début des années 2000.

Ce design pattern propose une utilisation cohérente et consistante des méthodes HTTP (RFC7231) comme unique moyen de communication entre un client et un fournisseur de service.

Par convention, à chaque méthode HTTP est associée un action :
- POST pour la création d'une ressource sur le serveur
- PUT pour la mise à jour d'une ressource
- GET pour la lecture
- DELETE pour la suppression

TODO HATEOAS ?

### JSON

Le format de données utilisé pour la communication avec w.c.s. est JSON (JavaScript Object Notation).
Cette notation déclarative permet la description d'objets, en fournissant un ensemble de type clé-valeur structuré.

Prenons l'exemple de la définition d'un schéma de formulaire par w.c.s :

```
json
{
    "always_advertise": true,
    "category": "test2",
    "category_id": "2",
    "confirmation": true,
    "description": null,
    "detailed_emails": true,
    "disabled": false,
    "disabled_redirection": null,
    "discussion": false,
    "enable_tracking_codes": false,
    "expiration_date": null,
    "fields": [
        {
            "label": "Email",
            "prefill": {
                "type": "none"
            },
            "required": true,
            "type": "string",
            "varname": "email"
        },
...
}
```

On remarque ainsi la façon dont listes et dictionnaires sont utilisées pour la description structurelles des différents champs définissant un objet.
(Champs multivalués, inclusion de sous-objets, etc).

### Plugin Passerelle
Le plugin passerelle fournit un ensemble de connecteurs permettant le dialogue entre w.c.s. et des sources de données et services de nature différentes.

Lors de la mise en place du POC, Passerelle a été utilisé pour l'établissement de la connexion LDAP depuis w.c.s.

Nous détaillons ici le scénario d'utilisation de Passerelle tel qu'implémenté dans le POC : Une fois l'entrée w.c.s. renseignée par l'utilisateur et complétée par l'agent, le plugin passerelle peut alors exploiter l'API REST pour aller chercher les données relatives aux réponses du formulaire, pour aller créer l'entrée LDAP.
L'interface avec le serveur OpenLDAP se fait à l'aide de la bibliothèque python `ldap3`.

La première étape de l'implémentation, après définition de l'interface, est l'écriture des fonctions du package `utils`, qui vont exploiter ldap3.

L'interface de LDAP n'est pas 'pythonique' et depassée, car basée sur l'idée que les opérations lourdes doivent être effectuées sur le client. //TODIG

Cf ldap3 abstraction layer

Une fois notre cas d'utilisaton spécifique de l'annuaire mis en place, nous tâchons d'implémenter un connecteur LDAP générique, basé sur le connecteur CSV déjà présent dans Passerelle.
Ce connecteur devra supporter un grand nombre d'opérations sur un annuaire du choix de l'utilisateur. Ainsi, l'interface de saisie de la requête LDAP laisse l'utilisateur libre de préciser tous les paramètres de la requête à effectuer sur l'annuaire.

La gestion des droits est laissée aux soins du serveur LDAP qui gère ses propres contrôles d'accès (par des ACL).

TODO Serveur, credentials et DN founis par l'utilisateur à la création du connecteur ? DONE

Il est nécessaire d'effectuer quelques recherches documentaires sur l'API python ldap3 pour la mise en place d'une interface Web de requêtes sur le connecteur.

Plusieurs points sont à mentionner ici:
- ldap3 prend en charge les modifications sur l'annuaire par utilisation d'un fichier LDIF (LDAP Data Interchange Format).

TODO http://ldap3.readthedocs.io/operations.html

### Config SMTP
Lors de la réalisation du POC, la phase de demande de création d'un compte invité sur le méta-annuaire
Une configuration SMTP est nécessaire pour l'automatisation des alertes email lorsqu'un
TODO rappel SMTP


## ReSTful APIs

# Mise en œuvre et réalisations

## Approvisonnement lors d'un WebSSO SAML2 – Cas des comptes invités
### Presentation
Dans le cadre du projet Campus Condorcet, les annuaires de différents établissements doivent être regroupés en un méta-annuaire central. Aussi des problématiques d'homogénéisation de données hétérogènes se pose.

La phase de travail préparatoire à la réalisation du projet a consisté en le développement d'un POC (*Proof Of Concept*) permettant d'illustrer la procédure de constitution du méta-annuaire.

Le POC implémente un mécanisme simple d'ajout d'un compte invité ayant recours à un fournisseur de service, qui lui même repose sur un fournisseur d'identité SAML2 configuré pour assurer le SSO (*Single Sign-On*).

### Déroulement de l'ajout du compte invité dans l'application POC

Suivant un scenario classique de SSO, l'authentification depuis le fournisseur de service (SP) est déléguée à un fournisseur d'identité (IdP). Le fournisseur d'identité conclut la phase d'authentification par le renvoi d'une assertion SAML validant l'authentification.

De nombreuses informations présentes dans l'assertion SAML seront ensuites réutilisées par le fournisseur de service. Le contenu complet de l'assertion SAML est consultable en annexes de ce document, à titre indicatif. On remarquera la normalisation de la majorité des entrées (noeuds, attributs, corps) XML des messages SAML.

En particulier, les champs SAML permettant d'identifier l'utilisateur connecté sont récupérés de l'assertion. Ces champs permettent de déterminer si l'utilisateur n'est pas déjà renseigné dans le méta-annuaire OpenLDAP (annuaire d'aggrégation des référentiels d'identités des établissements partenaires du projet).

Si l'utilisateur ne se trouve pas dans le méta-annuaire, la procédure d'ajout du compte doit être effectuée. Un formulaire est alors proposé à l'utilisateur, il lui permet de valider ses données d'identités et de choisir une unité d'affectation.

La création et la gestion du formulaire sont prises en charge par l'outil w.c.s. Cet outil se base sur la notion de workflow, c'est-à-dire la cohabitation de procédures automatisées de traitement de l'information d'un part, et le recours à des actions manuelles de la part d'agents d'autre part.

Une fois le formulaire rempli par l'utilisateur, le workflow est configuré pour l'envoi automatique d'un email à un agent, pour la confirmation de création du compte.

Le plugin Passerelle permet la communication avec l'annuaire, permettant l'ajout de l'entrée LDAP correspondant au compte nouvellement créé.

L'appel au plugin Passerelle doit être effectué en tant que phase du workflow. La validation de la demande doit être rendue possible par la génération d'un lien envoyé par email à l'agent.

### Déploiement:
7 briques majeures:
- SP
- IDP
- Gestion formulaires (WCS)
- Base de connecteurs (Passerelle)
- Serveur http (Apache)
- Annuaire OpenLDAP (slapd)
- serveur de mail (exim4)

## Cas d'usage et prototypage
### Description des cas d'usage

* Première partie : description de l'existant
=============================================

Nous étudierons ici une architecture logicielle telle qu'il est possible d'en trouver au sein d'une entreprise de structure standard.

Plusieurs référentiels d'identités sont présents au sein de l'entreprise, utilisé par les différents services métier.

Ainsi, les Ressources Humaines stockent les données d'identités des employés à l'aide d'un système de gestion de base de données relationnelle (SGBDR ou *RDBMS*).

Un annuaire de type Active Directory (implémentation LDAP propriétaire Microsoft) est mis en place pour différents usages. Il sert à l'authentification des employés à leurs postes client, mais aussi à la vérification des permissions pour le montage d'un système de fichier réseau (partition NFS).

Un serveur de mail (Microsoft Exchange) rassemble aussi les boîtes email des utilisateurs, et un serveur PABX est chargé des la commutation des numéros de téléphone internes attribués à chacun des employés.

Finalement, un serveur d'impression dispose de données utilisateurs pour la gestion des quotas et des permissions d'accès aux imprimantes de l'entreprise.


* Deuxième partie : approche fonctionnelle
==========================================

Deux documents pour la description fonctionnelle.

**`arch06.odg` est le schéma d'architecture fonctionnelle désirée pour le cas d'usage.**

**`sequence05.dia` est le diagramme de flux de la procédure d'approvisionnement et de synchronisation.**

L'approvisionnement d'utilisateur étudié ici sera celui dans le backoffice, destiné aux agents de l'entreprise. Il ne s'agit donc pas d'une base des clients, seulement des employés.
Différents éléments et briques logicielles sont à prendre en compte dans le cas de ce scénario :
- La gestion de la base RH
- Cette gestion implique une création dans l'AD
- La mise en place de l'annuaire AD permet la connexion de l'employé à son poste client
- De même l'AD permet l'accès à un système de fichiers partagé (en l'occurrence un serveur de fichiers Microsoft)
- La création d'un compte email (par exemple un serveur MS Exchange)

La problématique de l'approvisionnement comporte certains obstacles techniques.
Ainsi, on ne sait pas à quel(s) groupe(s) appartient l'employé lorsqu'il est ajouté dans l'annuaire Active Directory.
Après ajout dans l'AD, une intervention humaine est requise pour placer le nouveau profil dans les groupes adéquats.
Cette intervention sera effectuée par un.e administrateur/administratrice AD, averti.e par courriel de la création d'un nouveau compte.

Le workflow comprendra aussi création la création du profil dans le serveur PABX (téléphonie privée).
Les mêmes problèmes surviennent alors : on ne sait pas à l'avance dans quel bureau se situe l'employé dont on crée le compte.
L'action d'ajout dans le PABX sera alors associée elle aussi à une intervention humaine, qui consistera simplement à demander à l'administrateur téléphonie le numéro de téléphone associé au compte.

Le cas d'usage sera complété par le déploiement d'une plateforme Publik, et le compte créé sera aussi provisionné dans l'IDP Authentic de la plateforme.
Comme précédemment, la notification se fait par envoi d'un email, destiné à l'administrateur Publik, afin d'avertir ce dernier de la création d'un compte

Il faudra déterminer si l'ensemble des actions décrites ci-dessus peut être formalisé dans un unique *workflow*.
Au sein du ou des *workflows*, il faudra alors ordonner les différentes actions entre elles.
Nous pouvons d'ores et déjà ordonnancer certaines des étapes du workflow : il faut d'abord renseigner l'adresse email du nouveau compte dans le méta-annuaire.
La procédure de création sera ensuite complétée par un ajout dans la base Exchange (outil de messagerie Microsoft).
Il faudra par la suite mentionner l'adresse email dans la plateforme Publik. On viendra aussi modifier la base RH pour préciser l'adresse email créée.

Par ailleurs, le numéro de téléphone est provisionné dans Exchange, ainsi que dans la base RH et dans Publik. Il faudra déterminer si l'approvisionnement de ces différentes données utilisateur peut être effectué dans le même *workflow*.

Dans un second temps, nous abordons le cas où l'utilisateur demanderait à changer de nom d'usage. Le changement de nom doit être initié dans la base RH, car c'est elle qui centralise les données d'identité.
Une notification à l'administrateur concernant le changement est envoyée par email.
Il ne s'agit pas d'un changement complet dans la base RH, seulement de l'ajout d'un alias pour toutes les données impactées par la demande de changement (nom, email, username, _etc_). L'utilisateur restera ainsi joignable sous ses anciennes données d'identité.

Un dernier cas d'usage sera aussi pris en compte afin de venir compléter cette étude.
Dans ce cas d'usage, le point de départ est l'ajout d'une entrée utilisateur dans l'annuaire de messagerie. Qu'il s'agisse ou non d'un système de règles dans l'annuaire de messagerie, le meta-annuaire de synchronisation doit être en mesure d'aller pousser l'adresse dans la RH.


* Troisième partie : problématiques techniques
==============================================

Adoptons maintenant un point de vue plus technique pour l'élaboration de ce scenario d'utilisation.
Des mécanismes de duplication sont mis en place dans l'infrastructure de gestion des identités. La base Active Directory est ainsi répliquée vers un annuaire OpenLDAP. Sur cet annuaire s'exécute une application Web de type 'Pages blanches'.
L'interconnexion entre les deux annuaires est réalisée à l'aide de LSC (*LDAP Synchronization Connector*).

Les modifications de la base RH étant à l'origine de la plupart des procédures de synchronisation, nous devons aussi déterminer la façon dont sont détectées ces modifications. La base de données RH est implementée en SQL, par exemple postgreSQL.

On implémentera donc un script python, chargé de détecter ou de surveiller les changements dans la base. Ce script rendra compte des événements d'ajout, de modification ou de suppression d'entrées dans la table des profils (les événements remontés seront du type "Création de UserA", "Modification de UserB", "Suppression de UserC"). Ce script s'exécutera en tâche de fond (processus de type _daemon_), surveillant les changements apportés à la base.

On placera le même type de daemon pour surveiller les éventuels changements apportés par les agents à l'annuaire de téléphonie.
On rappelle que la notion de *workflow* implique nécessairement des actions humaines. Les demandes d'intervention d'agents seront prises en charge pour l'outil w.c.s.
L'application w.c.s devra alors implémenter un connecteur LDAP, afin de s'interfacer avec l'AD et l'annuaire de téléphonie.
On ajoutera à cela un connecteur vers l'API d'Authentic 2 (l'interface actuelle de w.c.s. avec A2 étant pour l'instant incomplète).

### Démonstrateur avec LSC (*LDAP Synchronization Connector*)

### Analyse de la couverture du besoin avec les outils Entr’ouvert

#### Architecture cible

#### Développements nécessaires

# Synthèse technique

// deux pages maxi

# Conclusion

# Annexes

## Acronymes
* ABAC : *Attribute-Based Access Control*
* ACI : *Access Control Index* [//]: <> (??)
* ACL : *Access Control List*
* AD : *Active Directory*
* ADFS : *Active Directory Federation Services*
* ALFA : *Abbreviated Language For Authorization*
* AS : *Authentication Server*
* BCN : Base Centrale des Nomenclatures
* BDB : *Berkeley DB*
* BLOB : *Binary Long OBject*
* BPM : *Business Process Management*
* BPMN : *Business Process Model and Notation*
* CADA : Commission d'Accès aux Documents Administratifs
* CAS : *Central Authentication Service*
* CBV : *Class-Based View*
* CCTP : Cahier des Clauses Techniques Particulières
* CDDL : *Common Development and Distribution Licence*
* CDN : *Content Delivery Network*
* CRM : *Customer Relationship Management*
* CSR : *Certificare Signing Request*
* (D)Dos : *(Distributed) Denial of Service*
* ECM : *Enterprise Content Management*
* EES : Etablissements de l'Enseignement Supérieur
* ESB : *Enterprise Service Bus*
* FFI : *Foreign Function Interface*
* FQDN : *Fully-Qualified Domain Name*
* GI : Gestion des Identités
* GIS : *Geographic Information System*
* GRC/GRU : Gestion de la Relation Citoyen/Gestion de la relation usager
* GSS (GNU ~ et ~-API) : *Generic Security Service*
* HSTS : *HTTP Strict Transport Security*
* I18N : *Internationalization*
* IAM : *Identity and Access Management*
* IANA : *Internet Assigned Numbers Authority*
* IDP : *Identity provider*
* IDM : *Identity Manager*
* IETF : *Internet Engineering Task Force*
* JPA : *Java Persistence API*
* JSON : *JavaScript Object Notation*
* JWS : *JSON Web Signature*
* JWT : *JSON Web Token*
* L10N : *Localization*
* LDAP : *Lightweight Directory Access Protocol*
* LDIF : *LDAP Data Interchange Format*
* LSC : *LDAP Synchronization Connector*
* MIME : *Multipurpose Internet Mail Extensions*
* MVCC : *Multi Version Concurrency Control*
* NDS : *Novell Directory Services* // Vraiment pertinent ici ? Mentionné dans la RFC3384
* NFS : *Network FileSystem*
* NIO : *Non-blocking I/O* (API Java)
* NTP : *Network Time Protocol*
* OASIS : *Organization for the Advancement of Structured Information Standards*
* OID : *Object IDentifier*
* OIDC : *OpenID Connect*
* ORM : *Object-Relational Mapping*
* OSGi : *Open Services Gateway initiative*
* OSI : *Open Systems Interconnection*
* OWASP : *Open Web Application Security Project*
* OWF : *One-Way Function*
* PABX : *Private Automatic Branch eXchange*
* PAM : *Pluggable Authentification Modules*
* PEP : *Python Enhancement Proposal*
* PKCE : *Proof Ket for Code Exchange*
* PKCS  : *Public-Key Cryptography Standards*
* POC : *Proof Of Concept*
* POM : *Project Object Model*
* PyPA : *Python Package Authority*
* RBAC : *Role-Based Access Control*
* RDBMS : *Relational DataBase Management System*
* RENATER : REseau NAtional de télécommunications pour la Technologie, l'Enseignement et la Recherche
* RFC : *Request For Comments*
* RNE : Répertoire National des Etablissements
* SAML : *Security Assertion Markup Language*
* SASL : Simple Authentication and Security Layer
* SGBDR : Système de Gestion de Base de Données Relationnelle
* SIRET : Système d'Identification du Répertoire des ETablissements
* SISE : Système d'Information pour le Suivi des Etudiants
* SPA : *Single-Page Application*
* SSHA : *Salted SHA*
* SOAP : Simple Object Access Protocol
[//]: <> (Nécessaire de revoir l'architecture SOAP ? Est-ce vraiment encore utilisé ?)
* SP : *Service Provider*
* SSO/SLO : *Single Sign-on / Single Log-Out*
* SVE : Saisie par voie électronique
* SVA : Silence vaut acceptation
* ToIP : *Text over Internet Protocol* (US) ou Téléphonie sur IP (FR)
* TTLS : *Tunnelled Transport Layer Security*
* UID : *Universal IDentifier*
* UUID : *Universal User IDentifier*
* VoIP : *Voice over Internet Protocol*
* WSBPEL : *Web Services Business Process Execution Language*
* WSDL : *Web Services Description Language*
* WSGI : *Web Server Gateway Interface*
* XACML : *eXtensible Access Control Markup Language*
* XMI : *XML Metadata Interchange*
* XSD : *XML Schema Definition*

## Quelques définitions
**Référentiel d'identités** : Un référentiel d'identités désigne le mécanisme de stockage des différentes données relatives aux identités des utilisateurs d'une application.
**Gestionnaire d'identités** (Abbréviation *IM*) : Il s'agit de l'application responsable de la manipulation des données fournies par le référentiel d'identités.
**Fournisseur d'identités** (Abbréviation *IdP*) : Son rôle est de mettre à disposition des services les données relatives aux identités des utilisateurs, à des fins d'authentification ou d'identification/autorisation, tout en mettant en place des fonctionnalités de traçabilité (*accounting*). [//]: <> (CF AAA dans la doc sur les IdP : Authentication, Authorization, Accounting)
**Approvisionnement** (En: *Provisioning*) : C'est la procédure de constitution (initiale ou continue) des référentiels d'identités. La source peut-être un autre référentiel, on parle alors de réplication. Au contraire, les données d'approvisionnement peuvent provenir des services qui accèdent en écriture à l'IdM/IdP (ex: application RH qui crée le profil d'un nouvel employé, ou script sysadmin d'ajout d'un nouvel utilisateur UNIX).
**Synchronisation** : On parle de synchronisation de référentiels d'identités lorsque la modification de données présentes sur l'un des référentiels engendre des modifications similaires, ou de même nature, sur un ou plusieurs autres référentiels. On remarquera que cette synchronisation peut aller plus loin qu'une simple duplication à l'identique des données sur plusieurs référentiels.
En effet, la synchronisation peut avoir lieu, même en l'absence d'identicité des méthodes ou des schémas de référencement utilisés.
La synchronisation peut aussi donner lieu à la création d'un référentiel centralisé regroupant un sous-ensemble de données des différents référentiels synchronisés. On parle alors de méta-annuaire.


## Bibliographie
* RENATER : A quoi sert la fédération d'identités ?
https://services.renater.fr/federation/introduction/a-quoi-ca-sert

* Wikipedia : Security Assertion Markup Language (SAML)
https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language

* IETF RFC3384 : LDAP Replication Requirements
https://www.ietf.org/rfc/rfc3384.txt

* IETF RFC2829 : Authentication methods for LDAP
https://tools.ietf.org/html/rfc2829

* Comment ça marche : Le protocole Kerberos
http://www.commentcamarche.net/contents/88-kerberos

* IETF RFC1510 : The Kerberos Network Authentication Service
https://www.ietf.org/rfc/rfc1510.txt

* OpenClassrooms : Présentation du concept d'annuaire LDAP
https://openclassrooms.com/courses/presentation-du-concept-d-annuaire-ldap

* Atlassian Documentation : How to write LDAP search filters
https://confluence.atlassian.com/kb/how-to-write-ldap-search-filters-792496933.html

* Python Packaging Authority : virtualenv
https://virtualenv.pypa.io/en/stable/

* Apache Syncope Documentation : Getting Started
https://syncope.apache.org/docs/getting-started.html

* Apache Syncope Documentation : Reference Guide
http://syncope.apache.org/docs/reference-guide.html

* Linux France : Configuration OpenLDAP sous Linux
http://www.linux-france.org/~nquiniou/module_sr1/openldap/ch31s04.html

* A. Meddeb : OpenLDAP tutorial - Installation and basic configuration
http://tutoriels.meddeb.net/openldap-tutorial-installation-and-basic-configuration/

* CentOS 5 Documentation : Managing access control
https://www.centos.org/docs/5/html/CDS/ag/8.0/Managing_Access_Control-Creating_ACIs_Manually.html

* Développez.com : Tutoriel sur le projet LDAP Apache Directory
http://rpouiller.developpez.com/tutoriels/java/tutoriel-sur-projet-ldap-apache-directory-serveur-plugin-eclipse-et-api-java/

* Eclipse Kepler Documentation : Tutoriel sur le projet LDAP Apache Directory
http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.stardust.docs.dev%2Fhtml%2Fhandbooks%2Fprogramming%2Fpg-ldap.html

* Isode : LDAP and X.500
http://www.isode.com/whitepapers/ic-6033.html

* Network World : X.500 vs LDAP
http://www.networkworld.com/article/2287928/infrastructure-management/x-500-vs--ldap.html

* IETF RFC1487 : X.500 Lightweight Directory Access Protocol
https://tools.ietf.org/html/rfc1487

* IETF RFC4533 : The LDAP Content Synchronization Operation
https://tools.ietf.org/html/rfc4533

* Entrouvert : Lasso Reference Manual
http://lasso.entrouvert.org/documentation/api-reference/index.html

* S. Downes : Authentication and Identification
http://www.downes.ca/post/12

* Development Doodles : User authentication with django-registration
https://devdoodles.wordpress.com/2009/02/16/user-authentication-with-django-registration/

* A. Flavell : Redirect in response to POST transaction
http://www.alanflavell.org.uk/www/post-redirect.html

* IETF RFC822 : Standard for ARPA Internet Text Messages
https://tools.ietf.org/html/rfc822

* IETF RFC1123 : Requirements for Internet Hosts -- Application and Support
https://tools.ietf.org/rfc/rfc1123.txt

* Django Documentation : Class-Based Views
https://docs.djangoproject.com/fr/1.10/topics/class-based-views/

* Développez.com : Introduction à `* args` et `* kwargs` (Tutoriel Python)
http://deusyss.developpez.com/tutoriels/Python/args_kwargs/

* Django Documentation : URL Dispatcher
https://docs.djangoproject.com/fr/1.10/topics/http/urls/

* W3C : Cool URIs don't change (T. Berners-Lee)
https://www.w3.org/Provider/Style/URI

* Django Documentation : How to use sessions
https://docs.djangoproject.com/fr/1.10/topics/http/sessions/

* stackoverflow : What is a context in Django?
http://stackoverflow.com/questions/20957388/what-is-a-context-in-django

* Django Documentation  : Internationalization (i18n)
https://docs.djangoproject.com/fr/1.10/topics/i18n/

* Python ldap3 module documentation
http://ldap3.readthedocs.io/tutorial.html

* IETF RFC4515 : LDAP String Representation of Search Filters
https://tools.ietf.org/search/rfc4515

* Django Documentation : Generic editing views
https://docs.djangoproject.com/fr/1.10/ref/class-based-views/generic-editing/

* J. Kaplan-Moss : Dynamic Form Generation
https://jacobian.org/writing/dynamic-form-generation/

* Django Documentation : Formsets
https://docs.djangoproject.com/fr/1.10/topics/forms/formsets/

* Python Documentation : The Python debugger (pdb)
https://docs.python.org/2/library/pdb.html

* Entr'ouvert wiki : Guide de survie OpenVZ
https://dev.entrouvert.org/projects/sysadmin/wiki/OpenVZ

* OpenVZ : Official wiki
https://wiki.openvz.org/Main_Page

* Linux France : Configuration d'Apache2
http://www.linux-france.org/prj/edu/archinet/systeme/ch24s04.html

* Django Documentation : How to use Django with Apache and mod_wsgi
https://docs.djangoproject.com/fr/1.10/howto/deployment/wsgi/modwsgi/

* DigitalOcean : How To Serve Django Applications with Apache and mod_wsgi on Ubuntu 14.04
https://www.digitalocean.com/community/tutorials/how-to-serve-django-applications-with-apache-and-mod_wsgi-on-ubuntu-14-04

* Django Documentation : The staticfiles app
https://docs.djangoproject.com/en/1.7/ref/contrib/staticfiles/

* Running Gunicorn
http://docs.gunicorn.org/en/latest/run.html

* DigitalOcean : 502 Bad Gateway Ngnix & Gunicorn
https://www.digitalocean.com/community/questions/502-bad-gateway-ngnix-gunicorn

* OpenClassrooms : Créer un paquet .deb
https://openclassrooms.com/courses/creer-un-paquet-deb

* OpenVZ : OS template cache
https://openvz.org/OS_template_cache

* OpenClassrooms : Introduction à jQuery
https://openclassrooms.com/courses/introduction-a-jquery-4

* The Gnu Privacy Guard (GnuPG)
https://www.gnupg.org/blog/index.html

* IETF RFC4880 : OpenPGP Message Format
https://www.ietf.org/rfc/rfc4880.txt

* Wikipedia : Base64
https://en.wikipedia.org/wiki/Base64

* Codepoint : WSGI tutorial
http://wsgi.tutorial.codepoint.net/

* PEP3333 : WSGI
https://www.python.org/dev/peps/pep-3333/

* T. O'Mahony : Understanding, setting up, accessing and serving media files and static files in Django
https://timmyomahony.com/blog/static-vs-media-and-root-vs-path-in-django/

* R. Fielding : Hypertext Transfer Protocol
https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23

* Django Documentation : How to use Django with FastCGI, SCGI, or AJP¶
https://docs.djangoproject.com/fr/1.8/howto/deployment/fastcgi/

*  Django Documentation : How to use Django with Gunicorn
https://docs.djangoproject.com/fr/1.10/howto/deployment/wsgi/gunicorn/

* Django Documentation : How to write reusable apps
https://docs.djangoproject.com/fr/1.10/intro/reusable-apps/

* Django Documentation : Creating a Source Distribution
https://docs.python.org/2/distutils/sourcedist.html

* M. Comitini : Simple setup to get started with nginx and SCGI.
http://www.web2pyslices.com/slice/show/1466/nginx-and-scgi

* CheckUpDown : HTTP Error 400 Bad request
http://www.checkupdown.com/status/E400_fr.html

* The Pro Git Book : Git on the Server - The Protocols
https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols

* PEP8 : Style Guide for Python Code
https://www.python.org/dev/peps/pep-0008/

* RENATER : Recommandations pour les annuaires de l'enseignement supérieur - SUPANN 2009
https://services.renater.fr/documentation/supann/2009/documentcomplet

* afferp : AGPL FAQ
http://www.affero.org/oagf.html

* LDAP Synchronization Connector : Homepage
https://lsc-project.org/doku.php

* LDAP Synchronization Connector : Current users
https://lsc-project.org/about/currentusers

* Java Community Process JSR 223 : Scripting for the Java Platform
https://www.jcp.org/en/jsr/detail?id=223 //OBSOLETE

* Alfresco Documentation : Authentication and synchronization with one ldap-ad subsystem
http://docs.alfresco.com/5.0/tasks/auth-example-oneldap-ad.html

* PaperCutNG Manual : Synchronize user and group details with LDAP
https://www.papercut.com/products/ng/manual/common/topics/sys-user-group-sync-ldap.html

* Linux France : L'annuaire LDAP
http://www.linux-france.org/prj/edu/archinet/systeme/ch51s02.html

* IETF RFC4918 : HTTP Extensions for Web Distributed Authoring and Versioning
https://tools.ietf.org/html/rfc4918

* RFC6749 : OAuth2
https://tools.ietf.org/html/rfc6749

* Benjamin Renard (Easter Eggs) : Documentation LdapSaisie
http://ldapsaisie.easter-eggs.org/doc/all-in-one/LdapSaisie.html

* PHP FPM : A simple and robust FastCGI Process Manager for PHP
https://php-fpm.org/about/

* Entr'ouvert : Gestion d'identité Supann - Documentation
http://doc.entrouvert.org/supann/

* LinuxQuestions :  How to add a new schema to openldap 2.4.11?
http://www.linuxquestions.org/questions/linux-server-73/how-to-add-a-new-schema-to-openldap-2-4-11-a-700452/

* Telecom SudParis : Migration vers SupAnn
http://www.it-sudparis.eu/s2ia/user/procacci/ldap/Ldap_int018.html

* Internet2 : eduPerson Object Class Specification
https://www.internet2.edu/media/medialibrary/2013/09/04/internet2-mace-dir-eduperson-201203.html

* Debian Package Tracker : Linux
https://tracker.debian.org/pkg/linux

* Python Documentation : Modules
https://docs.python.org/2/tutorial/modules.html

* Tutorial's Point : Assertions in Python
https://www.tutorialspoint.com/python/assertions_in_python.htm

* Stackoverflow : Differences between isinstance() and type() in python
http://stackoverflow.com/questions/1549801/differences-between-isinstance-and-type-in-python

* Django Documentation : Template Inheritance
https://docs.djangoproject.com/en/1.10/ref/templates/language/#template-inheritance

* Django Documentation : django.contrib.auth
https://docs.djangoproject.com/en/1.10/ref/contrib/auth/

* Procrastinating Developer : Using Configurable User Models in Django 1.5
http://procrastinatingdev.com/django/using-configurable-user-models-in-django-1-5/

* Zytrax Open : LDAP Schemas, objectClasses and Attributes
http://www.zytrax.com/books/ldap/ch3

* LDAP Linux HOWTO : The ldapsearch, ldapdelete and ldapmodify utilities
http://www.tldp.org/HOWTO/LDAP-HOWTO/utilities.html

* Entr'ouvert : Documentation du projet Publik - Glossaire
https://doc-publik.entrouvert.com/glossaire/

* OpenLDAP : The slapd configuration file
http://www.openldap.org/doc/admin24/slapdconfig.html

* Django Documentation : Testing in Django
https://docs.djangoproject.com/en/1.11/topics/testing/

* Django Documentation : User authentication in Django
https://docs.djangoproject.com/en/1.11/topics/auth/

* Python Documentation : PEP343 -- The "with" Statement
https://www.python.org/dev/peps/pep-0343/

* Django Documentation : Sending email
https://docs.djangoproject.com/en/1.11/topics/email/

* Django Documentation : How to write reusable apps
https://docs.djangoproject.com/en/1.11/intro/reusable-apps/

* Python Documentation : Python Packaging User Guide
https://packaging.python.org/

* Django Documentation : Cryptographic signing
https://docs.djangoproject.com/en/1.11/topics/signing/

* Python Enterprise Application Kit : The Quick Guide to Python Eggs
http://peak.telecommunity.com/DevCenter/PythonEggs

* PyPA : Contributor Code of Conduct
https://www.pypa.io/en/latest/code-of-conduct/

* Django Documentation : Exceptions
https://docs.djangoproject.com/en/1.10/ref/exceptions/

* Django Documentation : Migrations
https://docs.djangoproject.com/en/1.11/topics/migrations/

* Django Documentation : Pagination
https://docs.djangoproject.com/en/1.11/topics/pagination/

* pytz : World Timezone Definitions for Python
http://pytz.sourceforge.net/

* Django Documentation : Security in Django
https://docs.djangoproject.com/en/1.11/topics/security/

* Django Documentation : Performance and optimization
https://docs.djangoproject.com/en/1.11/topics/performance/

* Django Documentation : Middleware
https://docs.djangoproject.com/en/1.11/ref/middleware/

* Django Documentation : Serializing Django objects
https://docs.djangoproject.com/en/1.11/topics/serialization/

* Django Documentation : Django settings
https://docs.djangoproject.com/en/1.11/topics/settings/

* Django Documentation : Signals
https://docs.djangoproject.com/en/1.11/topics/signals/

* Django Documentation : System check framework
https://docs.djangoproject.com/en/1.11/topics/checks/

* Django Documentation : The messages framework
https://docs.djangoproject.com/en/1.11/ref/contrib/messages/

* Python Documentation : Built-in functions
https://docs.python.org/2/library/functions.html

* Django Documentation : Error reporting
https://docs.djangoproject.com/en/1.11/howto/error-reporting/

* Object Management Group : Business Process Model and Notation (BPMN)
http://www.bpmn.org/

* Aaron Parecki : OAuth 2 Simplified
https://aaronparecki.com/oauth-2-simplified/

* ForgeRock Confluence Documentation : Simple Reconciliation Between OpenIDM and LDAP
https://wikis.forgerock.org/confluence/pages/viewpage.action?pageId=14090271

* Wikipedia : NT LAN Manager
https://en.wikipedia.org/wiki/NT_LAN_Manager

* Python Package Index : Django Kerberos
https://pypi.python.org/pypi/django-kerberos

* DNSimple Support : A Records
https://support.dnsimple.com/articles/a-record/

* Wikipedia : List of DNS record types
https://en.wikipedia.org/wiki/List_of_DNS_record_types

* Debian Administration : MIT Kerberos installation on Debian
https://debian-administration.org/article/570/MIT_Kerberos_installation_on_Debian

* Alan Eliasen : GPG Tutorial
https://www.futureboy.us/pgp.html

* Indiana University : What is a keytab, and how do I use one?
https://kb.iu.edu/d/aumh

* MIT Kerberos Documentation : Configuring Kerberos with OpenLDAP back-end
http://web.mit.edu/kerberos/krb5-devel/doc/admin/conf_ldap.html

* Akadia : How to create a self-signed SSL Certificate
http://www.akadia.com/services/ssh_test_certificate.html

* Linux Magazine : Integrating LDAP and Kerberos
http://www.linux-mag.com/id/4738/

* MIT Kerberos Consortium Wiki : LDAP on Kerberos
k5wiki.kerberos.org/wiki/LDAP_on_Kerberos

* MIT Kerberos Documentation : Designing an Authentication System - a Dialogue in Four Scenes
https://web.mit.edu/kerberos/dialogue.html

* David Robillard (Another I.T. Blog) : Kerberos KDC with OpenLDAP 2.4 Back-End and SASL GSSAPI Authentication on CentOS 6.2
http://itdavid.blogspot.fr/2012/05/howto-centos-62-kerberos-kdc-with.html

* MarkLogic Community Documentation : Understanding and Using Security Guide - External Authentication
https://docs.marklogic.com/guide/security/external-auth

* Stanford Universiy IT : An Introduction to Keytabs
https://uit.stanford.edu/service/kerberos/keytabs

* Linux Journal : The m4 macro package
http://www.linuxjournal.com/article/5594

* OpenLDAP ML : kerberos and LDAP authentication
http://www.openldap.org/lists/openldap-software/200210/msg00744.html

* Psycopg : PostgreSQL database adapter for Python
http://initd.org/psycopg/docs/

//bibbm

## Extraits de code source

//Ou URLs vers un dépôt git public pour consultation du code

## Explications techniques

### Annuaires
Le premier concept étudié ici est le mécanisme d'annuaire, largement répandu dans les systèmes d'information.
On utilise le terme *directory* en anglais, et il faut comprendre cet outil comme un répertoire où les données sont structurées de façon à refléter l'organisation des entités qu'elles représentent.
Cette structuration passe par la hiérarchisation des hiérarchisation des données d'identités. Lors de la phase de conception de l'annuaire, il est par exemple possible de déduire la hiérarchisation des données d'identités par la structure organisationnelle des entités stockées dans l'annuaire.

Les annuaires numériques sont apparus parallèlement à l'apparition des réseaux privés, afin de recenser les différentes entités et ressources présente sur le réseau, ainsi que proposer un moyen d'identification de ces ressources (qui sont-elles ? comment les contacter ?).

Le premier système de service d'annuaire, toujours utilisé aujourd'hui, est DNS (*Domain Name Service*). Toutes les propriétés fondamentales de l'annuaire y sont déjà présentes : structuration arborescente des données, accès en lecture plus souvent qu'en écriture, architecture centralisée localement mais distribuée d'un point de vue global, possibilité d'étendre la structure de base pour prendre en charge de nouveaux cas d'utilisation, utilisation de protocoles réseaux standardisés.

Par la suite, Sun Microsystems a mis aussi point le protocole Yellow Pages, devenu par la suite NIS (Network Information Service). Outre la prise en charge des données relatives au réseau, NIS étend le principe d'annuaire aux mécanismes d'authentification sur une architecture client-serveur. Aux fichiers d'identités usuels des systèesm UNIX (`/etc/{passwd,shadow,group,...}`) viennent s'ajouter des données présentes sur un serveur NIS. Les principes de délégation de l'authentification à une autorité tierce sont introduits : on parle alors de fournisseur d'identité (ou IdP). NIS définit aussi les protocoles de communication client-serveur pour accéder à l'annuaire.

La capacité des annuaires à décrire des structures de nature vaste et complète est réalisée par la mise en place des annuaires X.500 par la CCITT/UIT-T (Union Internationale des Télécommunications). Les différents protocoles de communication client-serveur de X.500 sont normalisés par l'OSI.

Plus généralement, la question de la pertinence de l'utilisation d'un annuaire en fonction des cas d'utilisation se pose. En effet, les données d'identités peuvent tout aussi bien être stockées sur une base de données. Plusieurs critères de choix de la technologie utilisée entrent alors en jeu :
* Si les données sont plus souvent lues qu'écrites, alors un annuaire peut être plus pertinent.
* S'il est nécessaire de rendre compte de relations entre entités stockées, il peut être préférable de recourir à une BdD.
* S'il est nécessaire de standardiser la structuration des données de façon à garantir l'interopérabilité des services, ou bien de d'utiliser des protocoles de consultation du support de stockage standardisés, alors un annuaire est plus adapté qu'une SGBD.

Nous remarquerons toutefois que le mode d'accès aux différentes ressources du réseau peut être défini au cas par cas à l'aide d'outils tels que NSS (*Name Service Switch*). Ainsi, le fichier `/etc/nsswitch.conf` défini un ordre de priorité pour les différentes méthodes d'accès aux ressources telles que *passwd*, *shadow*, *group*, *hosts*, *aliases*.

La prochaine section de ce document traite du standard d'annuaire le plus utilisé actuellement, LDAP (*Lightweight Directory Accès Protocol*). Différentes implémentation de cette RFC seront ensuite présentés.


#### X.500

#### LDAP
##### Présentation générale
Il convient tout d'abord d'expliquer en quoi LDAP se démarque des technologies d'annuaire précédentes.

LDAP se veut une simplification de X.500, par définition d'une structure arborescente minimale relativement simple à déployer (et cependant largement extensible).
Ainsi, si LDAP et X.500 ont de nombreux points communs (par exemple les attributs et objets typés de façon similaire, ou encore les mêmes opérations d'accès à l'annuaire), leur fonctionnement diverge en de nombreux points :
- les premières versions de LDAP supportaient déjà TCP/IP, tandis que X.500 n'a longtemps supporté que ses propres protocoles réseau.
- LDAP définit un mécanisme de duplication des annuaires selon plusieurs cas d'usage (Cf paragraphe suivant consacré à LDUP).
- LDAP allège le nombre de fonctions présentes dans X.500, proposant ainsi un standard plus facilement implémentable (justifiant ainsi le plus grand nombre d'implémentations LDAP disponibles par rapport à X.500).

[//]: <> (clairement les tenants et aboutissants d'une telle standardisation pour description organisationnelle, à l'aide des schémas couramment utilisés nis, inetorg ?)

Etudions par exemple le schéma InetOrgPerson fourni par l'IETF. Ce schéma décrit la façon dont un employé est défini dans l'annuaire.
Ce schéma, défini de façon exhaustive par la RFC2798, reste bien évidemment extensible (afin de répondre à des besoins spécifiques, non-couverts par la RFC).
Au total, 27 attributs permettent de définir une InetOrgPerson : carLicense, departmentNumber, displayName, employeeNumber, employeeType, jpegPhoto, etc.

Une fois déclarés tous les types mis en jeu pour la défini d'une InetOrgPerson, la définition de cet objet peut avoir lieu :

`# inetOrgPerson`
`# The inetOrgPerson represents people who are associated with an`
`# organization in some way.  It is a structural class and is derived`
`# from the organizationalPerson which is defined in X.521 [X521].`
` objectclass ( 2.16.840.1.113730.3.2.2`
`   NAME 'inetOrgPerson'`
`   DESC 'RFC2798: Internet Organizational Person'`
`   SUP organizationalPerson`
`   STRUCTURAL`
`   MAY ( audio $ businessCategory $ carLicense $ departmentNumber $`
`    displayName $ employeeNumber $ employeeType $ givenName $`
`    homePhone $ homePostalAddress $ initials $ jpegPhoto $`
`    labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $`
`    roomNumber $ secretary $ uid $ userCertificate $`
`    x500uniqueIdentifier $ preferredLanguage $`
`    userSMIMECertificate $ userPKCS12 )`
`   )`

Deux choses importantes sont à remarquer pour cette définition.

Tout d'abord, et de façon similaires à tous les types utilisés dans les schémas standard, les objet (*objectClass*) possèdent un OID (ou *Object IDentifier*). Les OID standard, délivrés par l'IANA, permettent d'identifier de façon univoque un élément (objet, attribut, ou type) intervenant dans la définition d'un schéma LDAP.

[//]: <> (chaque OID correspond à la standardisation d'un attribut)
[//]: <> ( LDAP reprend le format de la norme X500 mais propose une spécification plus légère et plus facile à mettre en place. "L" pour *Lightweight* Fonctionne sur TCP/IP contrairement  DAP/X.500)

Ensuite, la définition des *objectClass* se fait à l'aide de mot-clés indiquant à l'administrateur système quels attributs peuvent entrer en jeu pour l'objet donné.
Les différents mot-clés, à savoir MUST et MAY, permettent de déterminer le caractère optionnel ou obligatoire de chacun des attributs.
Un objet peut comporter un ensemble d'attributs obligatoires (i.e. qui doivent être présents pour chacun occurrence de l'objet dans l'annuaire) et un ensemble d'attributs optionnels seulement.
La RFC4519 (*LDAP: Schema for user applications*) donne l'exemple de l'*objectClass* `groupOfNames` qui possède ces deux ensembles d'attributs obligatoires et facultatifs :
`      ( 2.5.6.9 NAME 'groupOfNames'`
`         SUP top`
`         STRUCTURAL`
`         MUST ( member $`
`               cn )`
`         MAY ( businessCategory $`
`               seeAlso $`
`               owner $`
`               ou $`
`               o $`
`               description ) )`


[//]: <> ( Les données sont organisées selon un schéma.)
LDAP spéficie aussi une interface de consultation de l'annuaire pour les clients autorisés (voir les outils client de type `ldap-utils`)
Par définition, les accès les plus fréquents se font en lecture plutôt qu'en écriture. On parle d'annuaire car ce référentiel est plus souvent consulté que modifié.
Il est important de remarquer qu'à travers les schémas, LDAP standardise la structure et l'organisation des données stockées dans l'annuaire. Cette standardisation a pour but de garantir l'interopérabilité entre structures organisationnelles.

Le stockage des données de l'annuaire peut se faire sur une BDD ou simplement sur un fichier.

On distingue quatre composantes - ou quatre modèles (cf *Understanding and deploying LDAP Directory Services*) :
- le modèle de nommage
- le modèle fonctionnel
- le modèle d'information
- le modèle de sécurité

##### Modèle de nommage
Ce modèle consiste en une convention de formation des DC (*Domain Components*)
Identification univoque par utilisation d'un DN (Distinguished Name), ou utilisation du RDN si pas besoin d'identifiant unique.

Attributs de base des entrées LDAP [//]: <> (TODO Courte présentation de ces différents attributs)
* dn (*Distinguished Name*)
* rdv (*Relative Distinguished Name*)
* objectClass
* dc (*Domain Component*)
* o (*Organization*)
* ou (*Organizational Unit*)
* cn (*Common Name*)
* sn (*Surname*)
* uid (*User IDentifier*)

Structure arborescente de représentation des données.


##### Modèle fonctionnel
Le modèle fonctionnel de la RFC LDAP se base sur les mécanismes de portées et de filtres pour les opérations CRUD.
La recherche d'entrées dans un annuaire se fait selon une portée (*scope*) :
- **base** : recherche seulement sur l'entrée LDAP mentionné dans la recherche
- **sub** : recherche récursive complète
- **one** : un seul niveau de profondeur à partir de l'élément mentionné dans la requête

Les filtres définissent leur propre syntaxe d'expressions régulières et d'expressions booléennes pour imposer des conditions logiques sur les attributs des entrées recherchées.

Prenons par exemple la requête suivante :
```
"(|(telephoneNumber=*)(mail=*)(street=*))"
```

La RFC stipule que le symbole `|` désigne l'opérateur logique OU. Ainsi, la recherche ci-dessus renvoie toutes les entrées (à partir du DN définissant le sous-arbre de recherche) dont l'un des trois champs `telephoneNumber`, `mail` ou `street` est désigné.

De façon similaire, l'opérateur logique ET est représenté par le symbole `&`.

On remarquera par ailleurs que la RFC standardise une syntaxe de requêtes étendue permettant d'exprimer des conditions logiques plus complexes que ce qui est présenté ici. Nous renvoyons le lecteur à la documentation en ligne abordant la notions de filtres étendus, notamment les paragraphes 2 et 3 de la RFC4515 (String representation of LDAP Search Filters).


Les filtres ne prennent sens que par association aux différentes opérations effectuable sur l'annuaire . Elles sont au nombre de 11 : *abandon*, *add*, *bind*, *compare*, *delete*, *extended*, *modify*, *modify DN*, *rename*, *search*, *unbind*. Ces opérations appartiennent chacunes à l'une des quatre catégories CRUD (Create,Read, Update, Delete).
De par la nature-même de la structure d'annuaire, les développeurs de  OpenLDAP ont pris le parti de proposer une implémentation optimisant les opérations de lecture au détriment des opérations d'écriture.

Enfin, il est important de noter que LDAP s'appuie sur les propriétés modulaires de SASL, lesquelles permettent délégation de l'authentification à un mécanisme tiers, spécialisé dans cette tâche.

//
//URLs Echappement par caractères hexadécimal préfixé par %
//`ldap[s]://<hostname>:<port>/<base_dn>?<attributes>?<scope>?&<filter>?<extensions>`
//
//Opérations côté client de type CRUD
//
//

##### Modèle d'information
Le modèle d'information de LDAP introduit deux notions importantes:
- Le DIT (*Directory Information tree*) est la structure de données adoptées par le protocole. Cette structure arborescente, en pratique souvent peu profonde (beaucoup de noeuds sont des feuilles), permet de représenter un vaste ensemble de structures de données.
 - Le DSE (*Directory Service Entry*) est une entrée du serveur, associée à une chaîne de caractère de longueur zéro. L'entrée DSE contient les méta-données de l'annuaire, telles que les `namingContexts`, le `vendorName`, les `supportedAuthPasswordSchemes` ou encore les `supportedSASLMechanisms`.

En fonction des schémas utilisés, certaines entrées peuvent contenir des attributs multivalués (une même personne peut posséder plusieurs adresses, être associées à plusieurs unités d'affectation, etc). On notera néanmoins que la RFC impose l'absence d'ordre dans la déclaration des attributs multivalués.

// La définition des schémas standard se fait par recours aux OIDs , attributeType et et OIDs // Redite...

##### Modèle de sécurité
On peut aussi choisir de mettre en place une authentification anonyme (en général ce mode d'authentification présente des droits d'accès moindres par rapport à une authentification identifiée).

Deux protocoles principaux pour assurer la sécurité par chiffrement des échanges client-annuaire :
- LADPS a recours a SSL // obsolète, non ?
- StartTLS, qui utilise TLS (successeur de SSL)

Le serveur peut avoir recours à des ACLs pour restreindre les droits d'accès du client après authentification de ce dernier.
Nous renvoyons le lecteur de ce document aux *man pages* de *slapd.conf(5)*, fichier de configuration du serveur OpenLDAP.
La syntaxe des ACL y est assurée par une gestion de droits de façon déclarative, sous la forme :
`access to <what> [ by <who> <access> <control> ]+`

//Finalement, l'authentification peut-être laissée à un mécanisme d'authentification forte ou du moins renforcée, à l'aide du protocole SASL. //Redite

##### Fonctionnnalités annexes
###### Réplication
// cf plus bas LDUP -> TODO reorganiser, expliquer les différentes raisons pour instaurer une redondance de l'annuaire sur plusieurs serveurs

###### Distribution
La distribution introduit un concept similaire, à des fins différentes.
Cette fois-ci il n'y a pas de redondance, mais éclatement de l'annuaire en plusieurs parties sur différents serveurs.
On parle de *referrals* (càd de référencement), c'est à dire que les entrées de l'annuaire sont réparties sur plusieurs sites logiques.

###### Liens symboliques
En lien avec le concept de distribution, l'introduction du mécanisme de liens symboliques dans la RFC permet d'éviter la redondance des données.
La mise en place d'alias au sein d'un même annuaire permet d'éviter cette redondance.
La RFC parle d'*aliasedObjectName* (RFC4512LDAP Directory Information Models - Section 2.6 : Alias Entries)

##### Schémas
Un schéma de données LDAP est défini au format LDIF. Certains standards sont définis par la IETF et disposent d'OID approuvés par l'IANA //a vérifier
Les fichiers LDIF d'un serveur LDAPv3 sont en général disponibles en tant que fichier texte sur le serveur.
Il y a alors la possibilité de modifier (déconseillé) ou d'étendre (préférable) des schémas existant pour les adapter au scenario d'utilisation du serveur d'annuaire.

##### LDAP Duplication/Replication/Update Protocols (ldup)
Le WG LDUP définit un mécanisme de duplication pour les annuaires LDAPv3.
Il ne s'agit pas de synchronsation à proprement parler (l'annuaire, l'implémentation, les schémas, les données sont identiques).
*LDAP Duplication/Replication/Update* -- LDAPv3

Différentes configurations prises en charge pour la réplication des données de l'annuaire :
- plusieurs maîtres (multi-master)
- maître - esclave

Cependant, LDUP concerne un seul annuaire, selon un modèle distribué master*s*/slaves, pas forcément centralisé.
Mais en pratique, il n'est pas toujours (voire pas souvent possible) d'avoir un seul annuaire LDAP. Certains outils ne supportent pas ce protocole.

On va donc avoir besoin d'un mécanisme de synchro de référentiels d'identités basés sur des technos hétérogènes.

// TODO Réorganisation des h3, ce n'est pas très clair

##### LDAPv3 Replication requirements (RFC3384)
Concepts fondamentaux :
* Réplication anonyme (*anonymous replication*) : source et cible sont identifiées mais pas authentifiées
* Zone de réplication (*area of replication*) : sous-partie de l'arborescence qui subit réplication. (=> Cette réplication ne concerne pas toujours la totalité de l'annuaire)
* Opération atomique : cf théorie de la synchro entre différents process
* Conflits : sur les informations répliquées (par ex deux changements non conciliables concernant la même sous-partie des données répliquées)
* OID Critique : Critique au sens de la réplication. Synchronicité entre modification d'un OID critique et propagation des modifications sur tous les réplicats.
* Mise-à-jour incrémentale (*incremental update*) : Mise à jour dont le contenu ne concerne que ce qui a été modifié, et non pas les données restées identiques entre les deux modifications
* Réplication à sens unique (*one-way replication*) -> par opposition à :
* Réplication bidirectionnelle (*two-way replication*) : changements locaux appliqués dans les deux sens pour parvenir à un état identique ~> 'LDAP merge'
* Réplicat esclave (*Slave replica*) : exemplaire du LDAP disponible en lecture seule seulement. Ne peut être instigateur de modifications sur son exemplaire local de l'annuaire.

##### Authentication methods for LDAP (RFC2829)
###### Motivations de la RFC
Les différentes considérations entrant en compte dans la pertinence de l'authentification à un annuaire sont les suivantes :
- Un accès frauduleux en lecture, ce qui revient à un vol de données (potentiellement sensibles)
- Le *Session hijacking* par vol des données d'authentification d'un client légitime obtenues sur l'annuaire //TODO pas très clair...
- Un accès frauduleux en écriture, c'est-à-dire la corruption des données de l'annuaire
- Une attaque de type 'déni de service' (DoS) sur l'annuaire
- Et plus généralement, une attaque de type *Man-in-the-middle*, avec tout cela que ça implique (Dégâts côté client et/ou côté serveur...)

###### Moyens mis en place
Le mécanisme principal assuré par les implémentations LDAPv3 est une politique de sécurité contrôle par d'accès (*access control policy*).
Derrière ce nom barbare se trouvent avant tout des règles d'accès au ressources, généralement sous forme de liste (ACL)
Une telle politique nécessite la définition d'attributs d'accès //TODO

##### Implémentations
###### OpenLDAP
OpenLDAP est l'implémentation UNIX de référence des annuaires compatibles LDAPv3.
Cette implémentation est disponible dans les dépôts de la plupart des distributions standard.
Sous Debian, le paquet à installer est `slapd`.

Certaines distributions proposent des *LDAP scripts* censés faciliter l'administration du serveur d'annuaire.
//Compatibility avec les LDAP scripts ?

TODO Ecrire un slapd.conf pour le convertir à la nouvelle syntaxe ?
BLOCKER Quels credentials par défaut ? DONE

Les différents fichiers de configuration et fichiers binaires de OpenLDAP sont répartis dans le système suivant la convention ci-dessous (cf tutoriels.meddeb.net) :
- /usr/lib/ldap/ : librairies des modules (overlay), fichiers binaires natifs
- /etc/ldap/schema/ : Schémas disponibles par défaut, fichiers texte.
- /etc/ldap/slap.d/ : Configuration dynamique, fichiers texte.
- /var/lib/ldap/ : Données, fichiers de la base de données installée.
- /var/run/slapd/ : Paramètres d’exécution, fichiers texte.

Une fois l'annuaire installé, le serveur dispose d'une configuration minimale, dont le dn est dérivé du hostname de la machine :
```
paul@spare:~$ ldapsearch -Y external  -H ldapi:/// -b dc=entrouvert,dc=lan -LLLSASL/EXTERNAL authentication started
SASL username: gidNumber=1003+uidNumber=1003,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: dc=entrouvert,dc=lan
objectClass: top
objectClass: dcObject
objectClass: organization
o: entrouvert.lan
dc: entrouvert

dn: cn=admin,dc=entrouvert,dc=lan
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
```
Nous possédons maintenant les informations nécessaires pour paramétrer Apache Directory Studio afin de naviguer (à l'aide de la GUI) dans l'annuaire nouvellement installé.

L'exécutable binaire ApacheDirectoryStudio pour Linux est disponible sur le site du projet Apache.

Le fichier Example.ldif, utilisé en local seulement, et obtenu sur `mcraig.org/ldif/Example.ldif` (license CDDL), permet de peupler l'annuaire pour refléter une structure organisationnelle générique.

Nous aurions tout aussi pu utiliser la fonction *populate* des ldap-scripts disponible pour Linux. [//]: <> (Retrouver ceux du cours réseau ? ldappopulate)

Le code source d'OpenLDAP étant ouvert, il est possible d'étudier certains aspects de l'implémentation. OpenLDAP définit sa couche 5 (du modèle OSI), y compris tous les message qui vont circuler sur le flux TCP.

Commençons par obtenir de code source :
`$ git clone git://git.openldap.org/openldap.git`

[//]: <> (<OpenLDAP directory>ldap/libraries/libldap/ldap-int.h)

Ligne ~ 145 :
```C
/*
 * This structure represents both ldap messages and ldap responses.
 * These are really the same, except in the case of search responses,
 * where a response has multiple messages.
 */

struct ldapmsg {
        ber_int_t               lm_msgid;       /* the message id */
        ber_tag_t               lm_msgtype;     /* the message type */
        BerElement      *lm_ber;        /* the ber encoded message contents */
        struct ldapmsg  *lm_chain;      /* for search - next msg in the resp */
        struct ldapmsg  *lm_chain_tail;
        struct ldapmsg  *lm_next;       /* next response */
        time_t  lm_time;        /* used to maintain cache */
};
```

Déduit plusieurs caractéristiques sur l'implémentation :
Présence d'un cache des messages LDAP.
Messages typés
ber encoded ?
Maintient une liste chaînée de messages (une liste par échange cli-serv ?)

###### OpenDJ
###### IBM RACF [//]: <> (??? Plus large que LDAP ??)

###### Microsoft Active Directory
TODO

###### ApacheDS (Apache Directory Server)
ApacheDS est une autre implémentation LDAPv3, créée par Alex Karasulu.
Nous pouvons aussi utiliser Apache Directory Studio en tant qu'implémentation LDAP ou simplement en tant qu'interface frontend. Dans la section précédente, nous l'utilisions simplement en tant qu'interface graphique de navigation dans un annuaire OpenLDAP.
Pour des raisons de stabilité constatée, nous privilégions ici une installation à l'aide du paquet Debian (fichier .deb) plutôt que du fichier binaire Java.

Le site Apache fait volontairement l'amalgame avec leur autre outil associé, nommé lui aussi ApacheDS (pour Directory Studio)

Nous pouvons toutefois émettre une première critique de l'outil ApacheDS, utilisé en tant que navigateur graphique d'annuaires: l'interface utilisateur, dérivée de l'IDE Eclipse, est difficile à manipuler. Comme Eclipse, les différentes procédures pour parvenir à ses fins dans l'IDE sont lourdes et peu intuitives.

Nous rappelons au lecteur que l'objectif ici est de mettre en place en parallèle plusieurs annuaires hétérogènes sur la machine locale, ceci dans le but de tester les fonctionnalités d'approvisionnement et de synchronisation de plusieurs gestionnaires d'identités.

La synchronisation de ces référentiels présente par ailleurs la difficulté de devoir fonctionner à partir de référentiels d'identités hétérogènes.

[//]: <> (BLOCKER : apacheds console default admin password ? pas grave, pas utile ici)

En tant qu'implémentation ouverte, alternative, d'un serveur LDAP, cette fois-ci écrite en Java, ApacheDS respecte les normes imposées par la RFC LDAPv3.

Par ailleurs, et outre les fonctionnalités client/serveur de la RFC, ApacheDS expose sa propre API. Le composant jar se comporte comme un module standard Java, c'est-à-dire embarquable dans tout type type d'appli Java.

A titre d'exemple, ApacheDS est implémenté nativement dans le projet Apache Geronimo (serveur d'application J2E de la fondation Apache, certifié Java EE 6). Il est aussi embarqué dans WildFly (anciennement JBoss).

En tant qu'implémentation compatible avec les RFC LDAPv3, le serveur LDAP ApacheDS écoute par défaut sur les ports 10389 (en clair ou chiffré avec StartTLS) et 10636 (SSL) (OpenLDAP -> 389 et 636 ?)
Suivant les mécanismes de sécurité réseau standard sous Unix/Linux, le port 389 laissé par convention au serveur LDAP est inférieur en valeur à 1024. Il s'agit donc d'un port système réservé, et il faut disposer es droits *root* pour écouter sur ce port.
C'est par ailleurs sur ce port standard LDAP qu'écoute le serveur `slapd`, disponible dans les dépôts apt Debian.

ApacheDS implémente un mécanisme de distribution des données : la répartition des entrées se fait dans des partitions, chacune contenant un *Directory Information Tree* (TODO ref necessaire)

Nous pouvons, à titre indicatif, donner la procédure d'ajout d'une partition dans l'annuaire :
Ici en utilisant JDBM B+Trees [//]: <> (Et Mavibot ? TODIG)

Apache Mavibot MVCC BTree
Successeur de JDBM pour l'implémentation des arbres de recherche balancés (*Balanced binary search trees*)

Le stockage dans des fichiers binaires est utilisé à des fins backup //Très brouillon, aller voir la doc TODOTODO

Le backup se fait par lecture des entrées de configuration de l'annuaire, au format LDIF (LDAP Data Interchange Format, comme ci--dessous :
`$ ldapsearch -D "uid=admin,ou=system" -w secret -p 10389 -h localhost -b "dc=example,dc=com" -s sub "(ObjectClass=*)" * + > backup.ldif`

//TODO : Expliquer la syntaxe d'une requête de base. Expliquer en quoi on est loin du SQL, par exemple. Cf requête tuto officiel :
`ldapsearch -h localhost -p 10389 -b "o=sevenSeas" -s sub "(cn=James Hook)" +`

[//]: <> (TODIG Onglet Replication de la config du server apacheDS en GUI client lourd)

Quels mécanismes assurant la sécurité des données de l'annuaire, des échanges clients/serveur ?
Contrôle d'accès ? -> Standardisé par la RFC LDAPv3 ?
La configuration est manipulable par écriture/lecture de fichiers LDIF dans <apacheds_base>/conf/../\*.ldif
###### LDAP Synchronization Connector (LSC)
Il s'agit d'un connecteur permettant la synchronisation entre ApacheDS et OpenLDAP TODIG
//Lire la doc, quelle configuration ? Quels cas d'usages ? Quelles limites ? Quels partis pris pour l'implémentation du connecteur ?
Simplement une interface entre deux APIs ?
Ou bien utilisation de mécanismes sous-jacents, càd qui ne se limitent pas strictement à l'API ?

Licence BSD
Ecrit en Java

Philosophie de l'outil LSC :
Scripts génériques, plus simple et plus stable que le développement de solutions en interne ?
Deux niveaux de synchro:
- L'identité d'une personne en tant que telle, c'est-à-dire les informations qui définissant son *compte*.
- Les informations annexes qui décrivent l'identité de la personne (numéro de téléphone, email, etc)

Pour la synchronisation, seulement trois opérations du schéma CRUD usuel sont retenues. Il n'y a pas besoin de lecture (READ)
CREATE, UPDATE et DELETE sont suffisants

La synchronisation est effectuée en deux phases:
- la première phase consiste en la synchronisation à proprement parler :
    * lecture des entrées du référentiel source.
      Seuls les attributs déclarés explicitement sont retenus (on parle d'attributs pivot)
    * //TODO Quelles différences entre pivotAttributes et fetchedAttributes ?
        => Attributs pivots : ceux dont la modification va engendrer un mécanisme de re-synchronisation ?
            NON : les attributs pivots servent à effectuer le mapping entre entrées source et destination
        => Attributs récupérés : ceux qui vont êtres synchronisés (vers un autre référentiel)
    * utilisation de JavaBeans pour le transfert des attributs sycnhronisés
    * verification que les conditions de synchronisations sont remplies avant d'effectuer les changements sur le référentiel source
- la seconde phase est une phase de nettoyage des référentiels synchronisés.
    Il s'agit de synchroniser les suppression effectuée sur l'un des référentiels. Le même système d'attributs pivots est utilisé pour le mapping des entrées entre plusieurs référentiels.

//'Success stories' sur le site de LSC pas assez détaillées
Exemple de la BPI qui génère un annuaire centrale à partir de plusieurs fichiers CSV

Installation
Un paquet Debian est directement fourni, il reste à l'installer avec `dpkg`. Le connecteur est manipulable à l'aide d'un service `systemd`.


### Schéma SupAnn 2009

#### Présentation du standard
SUPANN est une spécification de schéma d'annuaire propre à l'enseignement supérieur français.
//Calqué sur ou du moins inspiré par le modèle organisationnel universitaire aux Etats-Unis.

Repose sur un schéma LDAP standard

Besoins de sécurité justifient l'utilisation d'un seul schéma de référentiel d'identités pour l'ensemble des établissements de l'enseignement supérieur français (EES).
//En réalité, on dirait que chacun a sa propre compréhension du référentiel.

Pbatique, assez fortement nationale, de la fédération d'identités.
Nécessité de la conformité sémantique et syntaxique des données de l'annuaire de chaque établissement : condition nécessaire à la mise en place d'une fédération d'identités.

Nombreux éléments LDAP génériques (dcObject, organisationalUnit, etc.)
Notamment un attribut intéressant dans le cadre du POC : eduPersonPrincipalName

SupannRedId nécessaire aussi pour la pbatique des déménagements.

Mots-clé de préconisation au même titre que les RFC de l'IETF.
DOIT (EXIGÉ), NE DOIT PAS, DEVRAIT (RECOMMANDÉ), NE DEVRAIT PAS (NON RECOMMANDÉ) et PEUT (OPTIONNEL)

#### SUPANN et cadre légal
La CNIL impose 5 contraintes concernant les données  :
- finalité
- proportionnalité
- durée de conservation limitée
- sécurité/confidentialité
- respect des droits des personnes

#### Réutilisation de LDAP
LDAP plus performant qu'un SGBDR pour ce qui est des lectures de données.

#### Nomenclatures
Réutilisation de spécifications de EES concernant certains attributs SUPANN

Cf la Base Centrale des Nomenclatures
La nomenclature utilisée est mentionnée en début de valeur de l'attribut, entres accolades
Exemple donné dans la doc, {SISE}...
{SISE} symbolisant la nomenclature du système d'information pour le Suivi des Etudiants

On parle d'étiquetage des attributs

#### Profils multiples

Comment modéliser le lien entre les différents profils, rattachés à une seule identité réelle
TODO explication des différentes stratégies pou remédier à ce problème
attributs composites
référencement (système de pointeurs)
reconstitution d'un profil par informations contenues à différents endroits de l'annuaire -> contournement du problème par non-duplication des données
regroupement des profils d'une personne au sein d'un même groupe
aliases TODO pourquoi ?
pointeurs TODO


### Authentification et SSO

#### Kerberos (RFC1510)
TODO bouquin o'Reilly EN COURS

TODIG
- Mutual Authentication :
Le client s'authentifie auprès du serveur, et réciproquement. Cette double authentification limite les risque d'usurpation d'identité (*identity spoofing*)
Trusted Third-Party
SESAME's limited delegation

L'algorithme de chiffrement symétrique utilisé par Kerberos est DES.

Notion de principal

Chiffrement des tickets envoyés

Ticket delivery service

Les clés distribuées par le service (de délivrement de tickets) ont une durée limitée dans le temps, ce qui diminue le risque d'attaques de type *replay* (rejeu frauduleux d'une session par un tiers non autorisé).
On parle alors de clé de session.

##### Recommandations/spécifications de la RFC
###### Déroulement de la phase d'authentfication :
- Le client envoie une requête d'accès à un service donné,
- Le serveur d'authentification Kerberos renvoie les accès, chiffré avec la clé publique du client. Ces accès contiennent un ticket initial et une clé cde session (clé temporaire).
- Le client va utiliser le ticket pour contacter le serveur. Ce ticket contient l'identité du client et la clé de session chiffrée avec la clé publique du serveur (associé au service demandé par le client).
- La clé temporaire initie l'authentification (pas forcément mutuelle), puis la négociation d'un paramètres de communication chiffrée entre client et serveur.

###### Accès à l'AS
Deux façons de réaliser la première étape (demande d'accès du client au serveur d'authentification) :
* D'abord un TGT (*Ticket-Granting Ticket*) pour contacter le TGS (*Ticket-Granting Server*)
* Sinon, le TGS est un serveur d'application comme les autres, pas de méthode de communication spécifique.

L'accès à la base de données des principaux se fait selon le protocole KADM (Kerberos Administration).

###### *Realms* (Royaumes)
A un serveur d'authentification est associé un royaume. Les royaumes représentent donc une unité organisationnelle nécessitant un mécanisme d'authentification pour ses principaux.
On remarquera ainsi que le nom du royaume apparaît dans l'identifiant de tout principal de ce royaume.

Il peut cependant être intéressant de mettre en place des mécanismes de communication (et d'authentification) inter-royaume.

//TODO cross-realm operations
Ces communications inter-royaumes nécessitant que l'admin sys mette en place des clés prévues à cet effet. Elles permettront les échanes chiffrés entre les royaumes.

Concrètement, le TGS d'un royaume est enregistré en tant que principal du second royaume. Tout client local peut alors contacter le TGS distant à l'aide un TGT classique.

La communication entre deux royaumes peuvent transiter par plusieurs royaumes intermédiaires, pourvu qu'une clé inter-royaume soit disponible pour chaque échange direct.
On parle alors de chemin d'authentification (*authentication path*).

En conséquence, pour des raisons pratiques, on met en place une organisation hiérarchique des royaumes entre eux, selon une structure arborescente.
Dans un tel modèle, tout royaume a un père et potentiellement plusieurs fils.
Cette hiérarchie est déduite des chemins d'authentification usuels.

TODO Question : comment est mise en place la base de données de principaux ? revoir KADM dans le cas de plusieurs royaumes.

On remarquera enfin que le processus d'authentification n'est par nature pas transparent pour l'application. Elle connaît, à l'aide du ticket, les differents royaumes impliqués dans le chemin d'authentification. Elle peut alors en déduire la fiabilité du processus d'authentification en fonction des différents acteurs mis en jeu.

TODO : Section 1.2 (*Environmental Assumptions*) mérite d'être détaillée ici

##### Remarques concernant l'utilisation des *keytabs*
Automatisation de l'authentification Kerberos par mise en place d'un fichier contenant les clés de *principals*.


#### SAML
#### SAML
Basé XML
Standardisé par l'OASIS
Décrit des formats de données d'échange entre IDP et SP, à des fins d'authentification et d'autorisation des utilisateurs.

Utilisé pour le SSO des navigateurs

Une implémentation pour le SSO au niveau d'internet plus que d'un intranet ( intranet => Cookies seuls permettent d'assurer le SSO, car on sait quels technos Web sont en place dans le réseau interne)

Cf OpenSAML

Définition de rôles TODO explications access control

Méthode d'authentification laissée au choix des concepteurs du service
LDAP, RADIUS, AD, délégation à un compte réseau social proposant des services d'authentification, etc.

SAML2.0 depuis 2005

TODO : Récupérer le XML Schema décrivant SAML, se documenter sur XML Encryption

Clauses d'une assertion SAML :
- contenu de l'assertion en elle même ?
- temps d'émission de l'assertion
- émetteur
- sujet de l'assertion
- conditions de validité de l'assertion

Sens (usuel) des assertions : IdP -> SP
De ces assertions dépendent les contrôle d'accès défini par le SP pour l'utilisateur venant de s'authentifitier

Types de *statements* :
- Concernant une authentification
- Concernant un attribut
- Concernant une autorisation
auxquels sont associées trois mêmes types de requête provenant du SP

TODO SAML SOAP bindings ?

##### profils SAML
###### Profil navigateur/artefact  // TODO ?
###### Profil navigateur/http POST // TODO ?

##### SAML et sécurité
TLS
XML Signature, et XML Encryption //TODO ?
Ne spécifie pas de méthode de signature ou de chiffrement en particulier, juste des conventions de formatage pour leséchangés des paramètres de ces deux mécanismes (signature et chiffrement)

##### Structure des échanges SAML
//TODO cf doc Authentic

Schema de l'attribut SAML LDAP/X.500 'givenName' (extrait doc Authentic) :

`    <saml:Attribute`
`        xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"`
`        NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"`
`        Name="urn:oid:2.5.4.42" FriendlyName="givenName">`
`        <saml:AttributeValue xsi:type="xs:string"`
`            x500:Encoding="LDAP">Mikaël</saml:AttributeValue>`
`    </saml:Attribute>`

Normé par L'OASIS


#### OAuth

#### OIDC

#### NTLM
Microsoft Network LAN Manager
assure trois fonctionnalités de sécurité au sein d'un réseau LAN Windows :
- authentification
- intégrité
- confidentialité

protocole d'authentification *challenge-response*
en trois échanges
client envoie un NEGOCIATE_MESSAGE qui rend compte de ses fonctionnalités prises en charge
le serveur envoie un CHALLENGE_MESSAGE
client répond à l'aide d'un AUTHENTICATE_MESSAGE

Ces trois contraintes de confidentialit, d'intégrité et d'authentification nécessitent de recourir, côtés client et serveur, à des fonctions de hachage sur le mot de passe.
Il s'agit ainsi d'un scénario classique de sécurité LAN //TODO expliquer pourquoi.

Les fonctions de hachage assurent l'authentification car, les risques de collision de *hash* étant minimes, un *hash* correct témoigne de la connaissance du mot de passe côté client.
Elles assurent aussi l'intégrité car l'empreinte obtenue peut servir d'indicateur de la conformité des données d'identité envoyées.
Enfin, les valeurs de hachage envoyées sont opaques : on parle de fonction à sens unique (*One-way fonction* ou OWF). Cela signifie qu'il n'est en général pas possible d'effectuer l'opération complémentaire qui permettraient de revenir aux données initiales.

La documentation consultée ne mentionne pas comment sont assurées les contraintes d'identification, lesquelles ne sont peut-être pas cruciales dans un réseau LAN. C'est à dire que les risques d'usurpation d'identité seraient moindres dans un réseau local.

LM Hash et NT Hash, proprio MS
dérivées respectivement de DES et de MD4...

LanMan One Way Function (LMOWF) et NTOWF

Quelles particularités ?
