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
- // Verify format of session_id
- $session_id = $request->query['session_id'];
- if ( $sanitized_sesion_id !== $session_id ) {
- $response->send();
- die;
- }
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.