Skip to content

Intégration de services non Web

Aurélien Bénel edited this page Apr 28, 2016 · 15 revisions

Le sujet de la semaine est l'intégration de services non-Web à des services Web.

L'exemple qui sera pris sera celui d'un service LDAP (Lightweight Directory Access Protocol), service non-Web très largement utilisé dans les systèmes d'information des moyennes et grandes organisations.

Objectifs du TP

En nous appuyant sur le service LDAP de l'université, nous allons développer un adaptateur (adapter) et un mandataire (proxy) :

  • l'adaptateur permettra de "brancher" le service LDAP à une application prévue pour consommer un service Web,
  • le mandataire permettra de limiter les droits d'écriture (de cette même application sur le service Web initial) aux seuls utilisateurs référencés dans l'annuaire.

Adaptateur

On veut mettre en place un annuaire participatif. Au lieu de développer une application complète, on va réutiliser l'application Agorae et la "brancher" sur le service LDAP.

  1. À votre avis quelles entrées peut-on obtenir avec la commande suivante ?
ldapsearch -h "ldap.utt.fr" -x -b "ou=People,dc=utt,dc=fr" -s "sub" "(eduPersonAffiliation=student)"

Testez la. Puis remplacez student par faculty puis employee.

  1. Une partie du code de votre adaptateur a été développée. Récupérez la, installez-la puis lancez la :
git clone -b lo10 https://github.com/Hypertopic/ldap2hypertopic.git
cd ldap2hypertopic
npm install
node index.js

Ouvrez l'URI http://localhost:1337/corpus/faculty.

  1. Ce flux est-il conforme à la spécification d'un corpus selon Hypertopic ? Si oui, on devrait pouvoir le charger dans un consommateur compatible. Que manque-t-il ? En utilisant une bibliothèque, ajoutez les deux lignes de code nécessaire.

  2. Réessayez le consommateur. Jusqu'où pouvez-vous aller dans la navigation. Quelle autre partie de la spécification devez-vous implémenter ? Inspectez le fichier index.js. Où est le chemin déjà pris en charge ? Remplacez le par un tableau contenant également le nouveau chemin à ajouter. À quoi sert la variable filter ? Gérez le cas correspondant au nouveau chemin (au préalable, vous pouvez tester votre nouveau filtre en ligne de commande). Après avoir comparé la définition de la méthode init et son appel, gérez le cas correspondant au nouveau chemin. Testez le nouveau chemin directement dans le navigateur puis à travers le consommateur du service.

Mandataire

  • Étudiez le code Node.js d'un proxy HTTP. Pour vous aider à comprendre son fonctionnement, changez le nom des variables en requestIn, requestOut, responseIn et responseOut. Expliquez pourquoi et comment le "streaming" est utilisé.
  • Inspirez vous de ce code pour écrire un reverse proxy capable de déléguer toutes les requêtes de http://localhost:8080/{chemin} vers http://agorae.test.hypertopic.org/argos/{chemin}.
  • Étudiez le code suivant:
var http = require('http');
var ldap = require('ldapjs');
var app = require('express')();

var configuration = {
  port: 8080,
  upstreamHost: 'agorae.test.hypertopic.org',
  upstreamPort: 80,
  upstreamPath: '/argos',
  ldapUrl: 'ldap://ldap.utt.fr',
  ldapId: 'uid', 
  ldapBase: 'ou=Person,dc=utt,dc=fr' 
};

/**
 * @implement Express middleware.
 */
function parseHttpCredentials(request, response, next) {
  var authorization = request.headers.authorization;
  if (authorization) {
    var token = authorization.split(" ");
    if (token[0]=='Basic' && token.length>1) {
      var credentials = new Buffer(token[1], 'base64').toString().split(':');
      request.auth = {
        login: credentials[0],
        password: credentials.length>1 ? credentials[1] : ""
      };
    }
    next();
  } else {
    response.setHeader('WWW-Authenticate', 'Basic realm=Authorization Required');
    response.sendStatus(401);
  }
}

/**
 * @implement Express middleware.
 */
function checkAuthenticationOnLDAP(request, response, next) {
  var auth = request.auth;
  var directory = ldap.createClient({url: configuration.ldapUrl});
  var ldapDn = configuration.ldapId + '=' + auth.login + ',' + configuration.ldapBase;
  directory.bind(ldapDn, auth.password, function(err) {
    if (err) {
      response.setHeader('WWW-Authenticate', 'Basic realm=Authorization Required');
      response.sendStatus(401);
    } else {
      directory.unbind();
      next();
    }
  });
}

/**
 * @implement Express middleware.
 */
function proxy(requestIn, responseOut, next) {
  responseOut.send('À vous de le faire...');
}

app.all('*', proxy);

app.listen(configuration.port, function() {
  console.log('Server running port ' + configuration.port);
});
  • Documentez chaque middleware. Implémentez le proxy en vous basant sur ce que vous avez fait plus haut.
  • Modifiez ce code pour que seuls les personnes de l'UTT (étudiants et personnels) puissent faire des requêtes (pour cela votre reverse proxy se connectera au serveur LDAP de l'UTT).

Clone this wiki locally