Accueil > OpenID Connect OAuth Server par DnC > Développer > CloudSession : session partagée à travers le Web

CloudSession : session partagée à travers le Web

OAuth Server by DnC offre une solution de session partagée entre applications réparties sur le web, ce qui en fait le serveur d’authentification le mieux adapté pour construire des applications avancées, partageant des données en toute sécurité à travers le Web.

De quoi s’agit-il ?

Ordinairement, les serveurs d’authentification sont utilisés pour déléguer le contrôle d’accès à des serveurs de ressources Web de type REST, c’est à dire sans état, et donc sans considération d’un contexte de session. La notion de session se trouve limitée à l’application cliente, et ne peut se propager en dehors des limites de son serveur sans risque de sécurité.

OAuth Server by DnC vous offre CloudSession, qui vous permettra d’échanger en toute sécurité des informations entre applications et services Web, dans les deux sens.

Les données de sessions sont stockées et servies par le serveur d’authentification.

Pour cela, OAuth Server by DnC (OAuthSD) offre un point d’extrémité de session, auquel toute application inscrite sur le serveur d’authentification ayant reçu un identificateur de CloudSession et un jeton d’accès, ainsi que l’application cliente ayant initialisé la CloudSession, peut s’adresser pour partager les informations de session dans les deux sens.

Utilisateur propriétaire des données de session

Au moment de la création de la session, les données de session sont enregistrées avec le nom de l’utilisateur final connecté, correspondant au jeton d’accès.
Lors d’une lecture, le contrôleur session vérifie la cohérence entre l’utilisateur désigné par le jeton d’accès avec celui de l’enregistrement.

Le contrôleur interdit les manipulations de données par un utilisateur non connecté.

Seul l’utilisateur final connecté peut donc manipuler les données de la session qui lui correspond. Ceci justifie le titre de "session utilisateur" [1].

Le point d’extrémité de CloudSession

Dans l’implémentation de DnC, le serveur OAuth est étendu pour offrir un nouveau contrôleur Session. Le point d’extrémité de session se trouve à l’adresse suivante :

https://oa.dnc.global/oauth/session.php

Les requêtes doivent comporter l’Identificateur de CloudSession et le Jeton d’accès.

Identificateur de CloudSession

L’identificateur de CloudSession est défini librement par l’application cliente qui initialise la CloudSession. Cependant :
- L’identificateur doit être unique, ce qui peut donner lieu à collision au moment de la création de la session. Une bonne pratique est d’utiliser un hash d’une valeur aléatoire générée avec un salt.
- L’identificateur doit être composé de lettres (majuscules et minuscules, de chiffres, sans espace ni caractère spéciaux.

Seules peuvent participer à une CloudSession les applications ayant reçu un identificateur de CloudSession session_id propre à cette session.

La façon de transmettre l’identificateur de session aux différentes applications est laissée à l’appréciation du développeur [2]. Cela permet de définir quelles applications accèdent à la session, et de contrôler quand cela se produit.

Il est recommandé que l’application cliente valide la bonne forme de l’identificateur de CloudSession avant de l’utiliser. Le code de validation est le suivant :

PHP

  1. // Verify format of session_id
  2. $session_id = $request->query['session_id'];
  3. $sanitized_session_id = preg_replace('/[^A-Za-z0-9"\']/', '', $session_id);
  4. if ( $sanitized_sesion_id !== $session_id ) {
  5.     $response->send();
  6.     die;    
  7. }

Télécharger

Il est utile, mais non essentiel, que soit conservé secret l’identificateur de CloudSession. Comme toujours, il vaut mieux utiliser une liaison serveur-serveur que passer par le navigateur du client.

Jeton d’accès

Le jeton d’accès [3] délivré à l’application cliente, est transmis avec les requêtes pour vérifier que l’application est autorisée.

L’application cliente doit émettre le jeton d’accès avec la requête adressée au point d’extrémité session. Cependant, elle n’est pas tenue d’effectuer la vérification du jeton d’accès préalablement à l’utilisation de la CloudSession, car le contrôleur session effectue cette vérification. En cas d’échec, les messages d’erreur retournés sont les même que ceux retournés par le contrôleur resource.

Format des données de session

Les données de session sont formées d’un unique array associatif dont les clefs doivent être de type string. Les données sont transmises au contrôleur session, dans les deux sens, au format JSON.

Espace de validité de la CloudSession

Les développeurs doivent considérer les facteurs suivants pour évaluer la sécurité des données d’une CloudSession :
- Un identificateur de CloudSession n’a pas de limite de validité. OAuthSD conserve indéfiniment les données associées.
- Toute application en possession d’un jeton d’accès valide (et de l’identificateur de CloudSession) peut accéder aux données de CloudSession.

On notera qu’il n’y a pas de lien entre le jeton d’accès et l’identificateur de CloudSession. Ainsi, une application cliente qui aurait perdu son jeton d’accès peut accéder à la CloudSession après en avoir obtenu un nouveau.

Création d’une CloudSession

Une CloudSession ne peut être créée que par une application cliente inscrite avec le scope "session" et en possession d’un jeton d’accès valide.

Forme de la Requête

Pour initialiser une CloudSession, l’application appelle le point de terminaison de session, avec les paramètres suivants :
- mode=create,
- session_id : un identification de CloudSession de son choix,
- access_token : le jeton d’accès en provenance du client.

Réponse du serveur

En cas de succès, le serveur retourne une réponse HTTP 200.

Le corps de la réponse contient un tableau portant les informations suivantes :

index type valeur
status entier code HTTP
headers string Headers de la réponse
page string JSON Array :
success : true,
initial_client_id : ID de l’application cliente ayant initialisé la session
initial_user_id : ID de l’utilisateur final ayant initialisé la session
expires : instant de la fin de validité (long)
maj : instant de mise à jour des données

 

En cas d’échec, le corps de la réponse contient :

index type valeur
page string JSON Array :
error : titre de l’erreur,
error_description : description de l’erreur

La réponse HTTP ainsi que les valeurs de error et error_description sont les mêmes que pour une requête de validation de jeton d’accès, avec les définitions supplémentaires suivantes :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
409 session_error Session ID conflict Le session_id fourni est déjà utilisé
500 session_error Error while creating session Erreur de la base de données, la nouvelle session n’a pu être créée

Lecture des données de CloudSession

Forme de la Requête

La lecture des données de session se fait par l’appel du point de terminaison de session, avec les paramètres suivants :
- mode=read,
- session_id : l’identification de CloudSession en provenance du client,
- access_token : le jeton d’accès en provenance du client.

Voici un exemple avec les paramètres passés dans l’URL de la requête :

https://oa.dnc.global/oauth/session.php?mode=read&session_id=MonBelIdentificateurDeSessionf&token=0df45a21bc2356bbf8a291

Réponse du serveur

En cas de succès, le serveur retourne une réponse HTTP 200.

Le corps de la réponse contient un tableau portant les informations suivantes :

index type valeur
status entier code HTTP
headers string Headers de la réponse
page string JSON Array :
success : true,
initial_client_id : ID de l’application cliente ayant initialisé la session
initial_user_id : ID de l’utilisateur final ayant initialisé la session
expires : instant de la fin de validité (long)
data : données au format JSON
maj : instant de mise à jour des données

Notes :
- Afin de permettre aux développeurs d’effectuer des contrôles de sécurité, ainsi qu’à toute fin utile, les informations suivantes sont systématiquement retournées par le point d’extrémité "session" : initial_client_id, initial_user_id et expires. L’application tierce peut ainsi obtenir des informations sur l’application cliente et l’utilisateur final qui ont initialisé la CloudSession.

 

En cas d’échec, le corps de la réponse contient :

index type valeur
page string JSON Array :
error : titre de l’erreur,
error_description : description de l’erreur

La réponse HTTP ainsi que les valeurs de error et error_description sont les mêmes que pour une requête de validation de jeton d’accès, avec les définitions supplémentaires suivantes :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
500 session_error Error while reading session data Erreur de la base de données, la lecture des données a échouée.

Notes :
- Certains cas d’erreur, correspondant à des incohérences dans la requête, peuvent signifier une tentative d’intrusion et donnent lieu à un échec sans détail de l’erreur.

Ecriture des données de CloudSession

Forme de la Requête

L’écrture des données de session se fait par l’appel du point de terminaison de session, avec les paramètres suivants :
- mode=write,
- session_id : l’identification de CloudSession en provenance du client,
- access_token : le jeton d’accès en provenance du client,
- data : Tout ou partie des données de session sous la forme d’un array associatif au format JSON.

Voici un exemple avec les paramètres passés dans l’URL de la requête :

https://oa.dnc.global/oauth/session.php?mode=read&client_id=radar&session_id=MonBelIdentificateurDeSessionf&token=0df45a21bc2356bbf8a291&data={"balance": 1000.21,"id":12031,"nom":"foo"}

Cette façon de faire n’est pas recommandée et ne peut convenir pour les données de grande dimension. De plus, il convient d’URL-encoder et décoder le paramètre data. On préfèrera un envoi par POST :

...

La longueur maximale de la chaîne au format JSON est d’environ 16Mo (16777212 octets).

Réponse du serveur

En cas de succès, le serveur retourne une réponse HTTP 200.

Le corps de la réponse contient un tableau portant les informations suivantes :

index type valeur
status entier code HTTP
headers string Headers de la réponse
page string JSON Array :
success : true

 

En cas d’échec, le corps de la réponse contient :

index type valeur
page string JSON Array :
error : titre de l’erreur,
error_description : description de l’erreur

La réponse HTTP ainsi que les valeurs de error et error_description sont les mêmes que pour une requête de validation de jeton d’accès, avec les définitions supplémentaires suivantes :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
500 session_error Error while writing session data Erreur de la base de données, la création de la session a échouée.
503 session_error Busy Avant d’écrire dans la base de données, le contrôleur vérifie qu’il n’y a pas déjà une écriture en cours sur la même session, et attend quelques dizaines de millisecondes avant de tenter à nouveau l’écriture. A ce moment, si une écriture est toujours en cours, l’écriture objet de la requête courante est abandonnée et cette erreur est générée. Il est de la responsabilité de l’application de recommencer l’écriture [4].

Codes d’erreur communs aux différents modes

Outre les erreurs communes avec la vérification du jeton d’accès, les erreurs suivantes sont communes aux différents modes de CloudSession :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
403 session_error Missing "session" scope for this client Le scope "session" n’a pas été autorisé pour l’application.
400 session_error Unknown session mode in request Le paramètre mode est inconnu

A propos du scope "session"

Pour pouvoir bénéficier du service de CloudSession, l’application cliente doit être inscrite avec le scope "session".

L’utilité du scope session est double :
- il permet de définir quelles sont les applications clientes autorisées à initialiser une CloudSession,
- ce scope peut être retiré à une instance d’une application cliente (et donc l’usage de CloudSession interdit) à la suite d’une authentification douteuse, par exemple sur l’action de Identity by DnC.

Notes

[1Au niveau des applications participant à la session, une pratique intéressante serait de synchroniser la session locale au moyen de l’identifiant de session. Cela rejoint la technique de gestion de session utilisée notamment par les application à page unique (Single Page Application, SPA).

[2A ce stade de la réflexion, on peut penser que les méthodes de transmission de l’id de session sont analogues à celles qui sont employées pour la connexion unique (Single Login Identification, SLI) et le renouvellement silencieux de l’autorisation (Silent Re-authentication) ou le Draft : Management de session OpenID Connect et qui font appel aux cookies de serveur et/ou aux iframe invisibles. La sécurité de ces techniques reste à évaluer.

[3Il s’agit du jeton opaque OAuth 2.0. Dans le cas d’OPenID Connect, ce jeton est toujours transmis parallèlement à l’ID Token.

[4On notera qu’il s’agit du mode "pessimiste" de gestion des collisions d’écriture, qui est la seule façon de procéder avec rigueur.