Il convient de faire une remarque importante en faveur du jeton d’accès (par rapport au jeton d’identité) : le jeton d’accès suffit au serveur pour identifier l’application cliente et l’utilisateur connecté. En effet, même si le jeton d’accès est opaque pour les applications clientes, il est enregistré dans la base de données du serveur OAuthSD (table access_token) avec l’ID du client (champ client_id) et l’ID de l’utilisateur connecté (champ user_id), sans oublier la date limite de validité (champ expires). on se réfère à ces données pour établir le fait que l’utilisateur est connecté ou non.

Donc, le jeton d’accès est indispensable pour toutes les applications le retournant au serveur pour vérification de la connexion de l’utilisateur (par exemple pour utiliser la session de l’utilisateur sur le serveur d’authentification, pour gérer les sessions d’une application à page unique (SPA) etc.).

Bien que le jeton d’accès soit opaque pour le client, il existe une méthode de vérification au moyen de la déclaration at_hash du jeton d’identité transmis conjointement par OpenID Connect.

OpenID Connect permet d’effectuer l’essentiel du SSO en toute simplicité. Mais plus on avance vers des implémentations complexes avec des cahiers des charges avancés, plus l’intérêt du jeton d’accès devient évident. C’est la raison pour laquelle le contrôleur token d’OpenID Connect retourne le jeton d’accès avec le jeton d’identité. OpenID Connect n’est-il pas une application avancée du jeton d’accès ?

OAuth 2.0 : Obtenir un jeton d’accès

, par DnC

L’application cliente doit disposer d’un jeton d’accès pour obtenir des données protégées de la part d’un serveur de ressources.

Au préalable, l’application doit avoir obtenu un jeton d’autorisation auprès du serveur (point de terminaison authorize).

Le code nécessaire est entièrement à la charge de l’auteur de l’application cliente, en réaction à la redirection sur l’URI du point d’extrémité de redirection. La méthode dépend du flux d’autorisation : avec Authorization Code Grant, l’application cliente doit d’abord obtenir un code d’autorisation.

Point d’extrémité de jeton (Token Endpoint)

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

Le point d’extrémité de jeton est le point d’extrémité sur le serveur d’autorisation auquel s’adresse l’application cliente avec le code d’autorisation, l’ID client et le secret, pour obtenir un jeton d’accès.

C’est également à ce point qu’une application s’adresse pour Rafraîchir un jeton d’accès.

Forme de la demande de jeton d’accès

La demande ne doit être effectuée que par la méthode POST.
Les paramètres suivants doivent être postés :
- grant_type : Type de flux d’autorisation, par exemple "authorization_code".
- code : le code d’autorisation reçu.
- client_id : l’ID de l’application cliente.
- client_secret : le secret de l’application cliente.

Le client inclut également ses informations d’authentification telles que décrites à la section 2.3. du document [RFC6749].

Les valeurs données pour les paramètres grant_type, client_id et client_secret doivent correspondre aux valeurs définies lors de l’inscription de l’application cliente sur le serveur.

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
page JSON array access_token : jeton d’accès

Le Header comporte, comme il se doit, la directive ’Cache-Control : no-cache, no-store’.

 

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

index type valeur
page 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 données par le tableau suivant :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
405 invalid_request The request method must be POST when requesting an access token La méthode de la demande doit être POST lorsque vous demandez un jeton d’accès. Notez que le Header contient ’Allow : POST’
400 invalid_request The grant type was not specified in the request Le type d’autorisation n’a pas été spécifié dans la demande
400 unsupported_grant_type Grant type "X" not supported Le Type d’autorisation "X" n’est pas supporté.
400 invalid_grant X doesn\’t exist or is invalid for the client Le type d’autorisation indiqué n’existe pas ou est invalide pour le client
400 unauthorized_client The grant type is unauthorized for this client_id Le type d’autorisation n’est pas autorisé pour ce client_id
400 invalid_scope The scope requested is invalid for this request La portée d’autorisation demandée est invalide pour cette demande
400 invalid_scope The scope requested is invalid for this client La portée d’autorisation demandée est valide pour ce client
400 invalid_scope An unsupported scope was requested La portée d’autorisation demandée n’est pas supportée

Exemples de code

Données de la requête :
- $AuthCode est le code d’autorisation obtenu à l’étape précédente et transmis à la page de CallBack
- $client_id, $client_secret : Comme indiqué lors de l’inscription de l’application cliente sur le serveur d’autorisation.

PHP

  1. // Demander un jeton d'accès pour l'application
  2. $jeton = '';
  3.  
  4. $url = 'https://oa.dnc.global/oauth/token.php';
  5.  
  6. $datas = array(
  7. 'grant_type' => 'authorization_code',
  8. 'code' => $AuthCode ,
  9. 'client_id' => 'XXXXXX',
  10. 'client_secret' => 'XXXXXXXXXXX',
  11. );
  12.  
  13. $ch = curl_init();
  14.  
  15. curl_setopt($ch, CURLOPT_URL, $url);
  16. curl_setopt($ch, CURLOPT_POST, true);
  17. curl_setopt($ch, CURLOPT_POSTFIELDS, $datas);
  18. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  19. curl_setopt($ch, CURLOPT_HEADER, false);
  20. curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  21. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  22.  
  23. $result_json = curl_exec($ch);
  24. $result = json_decode($result_json, true);
  25.  
  26. $token = $result['access_token'];
  27.  
  28. curl_close($ch);

Télécharger

SPIP

  1. $jeton = '';
  2. $url = 'https://oa.dnc.global/oauth/token.php';
  3. $options = array(
  4. 'method' => 'POST',
  5. 'datas' => array(
  6. 'grant_type' => 'authorization_code',
  7. 'code' => '$AuthCode',
  8. 'client_id' => 'XXXXXX',
  9. 'client_secret' => 'XXXXXXXXXXX',
  10. )
  11. );
  12.  
  13. $res = recuperer_url($url, $options);
  14.  
  15. $page = json_decode($res['page'], true);
  16.  
  17. $token = $page['access_token'];

Télécharger

Compléments à propos du type de flux JWT Bearer

Comme son nom l’indique, ce flux d’autorisation transporte un jeton JWT (JSON Web Token) au lieu d’un simple jeton opaque. Ce faisant, la validation du jeton est plus sûre et des informations sur l’application et l’utilisateur sont directement véhiculées par le jeton.

Le type de flux JWT Bearer réclame plus de paramètres dans la requête et effectue des vérifications concernant l’application cliente et l’utilisateur final.

En plus des paramètres décrits précédemment, JWT Bearer demande que le paramètre suivant lui soit posté :
- assertion : Un jeton JWT.

Par exemple, dans le cas d’un flux d’autorisation (Authorization Code Grant) :

POST /token.oauth2 HTTP/1.1
    Host: oa.dnc.global
    Content-Type: application/x-www-form-urlencoded
    grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhtpZCI6IjE2In0.eyJpc3Mi.J9l-ZhwP.

Dans le cas d’un flux d’authentification d’une application cliente (Client Authentication), le contrôleur Token met en oeuvre l’interface ClientAssertionType. Il faut alors fournir (voir RFC 7523) :
- client_assertion_type : urn:ietf:params:oauth:grant-type:jwt-bearer,
- client_assertion : Un jeton JWT.

Par exemple :

POST /token.oauth2 HTTP/1.1
    Host: as.example.com
    Content-Type: application/x-www-form-urlencoded

    grant_type=authorization_code&
    code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&
    client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhtpZCI6IjE2In0.eyJpc3Mi.J9l-ZhwP.

En cas d’échec, la réponse HTTP ainsi que les valeurs de error et error_description sont données par le tableau suivant :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
400 invalid_request The request method must be POST when revoking an access token La méthode de la demande doit être POST lorsque vous révoquez un jeton d’accès
400 invalid_request Missing parameters : "assertion" required Le parmètre assertion, passant le jeton JWT manque
400 invalid_request JWT is malformed
400 invalid_grant Invalid issuer (iss) provided
400 invalid_grant Invalid subject (sub) provided
400 invalid_grant Expiration (exp) time must be present
400 invalid_grant JWT has expired
400 invalid_grant Expiration (exp) time must be a unix time stamp
400 invalid_grant JWT cannot be used before the Not Before (nbf) time
400 invalid_grant Not Before (nbf) time must be a unix time stamp
400 invalid_grant Invalid audience (aud) Le paramètre audience ( Token Endpoint URI, URI du point de terminaison de jeton) est invalide
400 invalid_grant JSON Token Identifier (jti) has already been used
400 invalid_grant Invalid issuer (iss) or subject (sub) provided La clé publique n’a pas été trouvée pour le couple issuer (iss) - subject (sub) fourni par le jeton
400 invalid_grant JWT failed signature verification

Rafraîchir un jeton d’accès

, par DnC

Le rafraîchissement d’un jeton d’accès (Access Token Refresh) permet à une application cliente d’en prolonger la validité. La demande est faite au Point d’extrémité de jeton (Token Endpoint) en mentionnant le type de flux "refresh_token".

Les jetons de rafraîchissement ne sont fournis (et le sont alors systématiquement) que lors de la récupération d’un jeton avec les flux Autorisation via un code (Authorization Code Grant) et Autorisation via un mot de passe (User Credentials, Resource Owner Password Credentials Grant).

Note : cet article s’applique aussi bien à OpenID Connect qu’à OAuth 2.0.

Forme de la demande de rafraîchissement d’un jeton d’accès

La demande ne doit être effectuée que par la méthode POST.
Les paramètres suivants doivent être postés :
- grant_type : "refresh_token".
- refresh_token : le code de rafraîchissement reçu avec le jeton d’accès.
- client_id : l’ID de l’application cliente.
- client_secret : le secret de l’application cliente.

Les valeurs données pour les paramètres client_id et client_secret doivent correspondre aux valeurs définies lors de l’inscription de l’application cliente sur le serveur.

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
page JSON array access_token : jeton d’accès

Le Header comporte, comme il se doit, la directive ’Cache-Control : no-cache, no-store’.

 

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

index type valeur
page 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 données par le tableau suivant :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
400 invalid_request Missing parameter : "refresh_token" is required Paramètre manquant : "refresh_token" est attendu
400 invalid_grant Invalid refresh token Jeton de rafraîchissement non valide
400 invalid_grant Refresh token has expired Le jeton de rafraîchissement a expiré

Ainsi que quelques autres réponses identiques à la demande d’un jeton d’accès.

Exemple de code

SPIP

  1. ...
  2. // Rafraîchir le jeton expiré
  3. $options = array(
  4. 'methode' => 'POST',
  5. 'datas' => array(
  6. 'grant_type' => 'refresh_token',
  7. 'refresh_token' => $_SESSION['oauth_refresh_token'],
  8. 'client_id' => 'XXXXX',
  9. 'client_secret' => 'XXXXXXXXXXXXXX',
  10. ),
  11. );
  12.  
  13. $url = "http://oa.dnc.global/oauth/token.php";
  14. $refresh_response = recuperer_url($url,$options);
  15. $refresh_status = (int)$refresh_response['status'];
  16.  
  17. if ( $refresh_status == 200 ) {
  18. $_SESSION['oauth_access_token'] = $refresh_response['access_token'];
  19. return true;
  20. } else return false;
  21. ...

Télécharger

Attention :
Pour pouvoir rafraîchir un jeton d’accès, l’application cliente doit avoir été inscrite avec le Grant Type "Refresh Token" :

Note à propos de la sensibilité du jeton de rafraîchissement

Le jeton de rafraîchissement permet à l’application de demander au serveur d’émettre directement un nouveau jeton d’accès et/ou un nouveau jeton d’identification, sans avoir à authentifier à nouveau l’utilisateur. Cela fonctionnera tant que le jeton d’actualisation n’a pas été révoqué.

On comprendra qu’il convient de n’utiliser ce jeton que dans une relation serveur-serveur. C’est pourquoi l’obtention d’un jeton de rafraîchissement n’est possible qu’avec les flux Autorisation avec Code (Authorization Code Grant) ou Autorisation via mot de passe (User Credentials, Resource Owner Password Credentials Grant) [1] .

Il est indispensable que l’application cliente stocke ce jeton de façon la plus sécurisée possible. Les bonnes pratiques suivantes devront être appliquées au jeton de rafraîchissement [2], sous peine de détruire la sécurité des flux considérés :
- le jeton de rafraîchissement ne doit pas être enregistré dans un cookie ;
- le jeton de rafraîchissement ne doit pas être passé en paramètre d’URL ;
- ... ?

Notes

[1Dans la liste déroulante, OAuthSD présente la possibilité d’utiliser le jeton de rafraîchiisement conjointement à tous les flux ; bien entendu cela ne fonctionnera que pour les "bons" flux.

[2Ainsi qu’aux autres jetons !

Révoquer un jeton

, par DnC

Le sujet est couvert par le document RFC 7009 OAuth 2.0 Token Revocation.
Ce document propose un point d’extrémité supplémentaire pour le serveur d’autorisation OAuth, qui permet aux clients d’avertir le serveur d’autorisation qu’un jeton de rafraîchissement ou d’accès précédemment obtenu n’est plus nécessaire. Cela permet au serveur d’autorisation de nettoyer les données de sécurité. Une demande de révocation invalidera le jeton en question et, le cas échéant, d’autres jetons basés sur la même autorisation.

Point d’extrémité de Révocation

OAuth Server by DnC expose le point de terminaison ’revoke’ pour la révocation d’un jeton d’accès ou de rafraîchissement :

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

Forme de la demande de Révocation

La demande ne doit être effectuée que par la méthode POST.
Les paramètres suivants doivent être postés :
- token (obligatoire)
- token_type_hint (optionnel) : ’access_token’ ou ’refresh_token’. Peut être manquant ou même erroné, le serveur recherchera le token parmi tous les types possibles.

Le client inclut également ses informations d’authentification telles que décrites à la section 2.3. du document [RFC6749].

Exemple de requête :

POST /revoke HTTP/1.1
    Host: oa.dnc.global
    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

    token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token

En cas de succès ou si le jeton est invalide, le serveur retourne une réponse HTTP 200.

Remarque : les jetons non valides ne provoquent pas de réponse d’erreur puisque l’objet de la demande de révocation, invalider le jeton désigné, est déjà atteint.

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

index type valeur
page 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 données par le tableau suivant :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
400 invalid_request The request method must be POST when revoking an access token La méthode de la demande doit être POST lorsque vous révoquez un jeton d’accès
400 invalid_request Token type hint must be either "access_token" or "refresh_token" Le type de jeton doit être "access_token" ou "refresh_token"
400 invalid_request Missing token parameter to revoke Il manque le type du jeton à révoquer

Validation du jeton d’accès par interrogation du serveur d’autorisation (Introspection)

, par DnC

La norme OAuth 2.0 n’indique pas comment les serveurs de données protégées qui reçoivent un jeton d’accès doivent procéder pour le valider, que ce soit localement ou en s’adressant à point d’entrée dédié à sa validation [1] [2].

Avec OAuth Server by DnC, les applications peuvent accéder au point d’extrémité "resource " pour valider le jeton d’accès reçu. Le standard "Introspection Endpoint" est également implémenté.

Les données de profil de l’utilisateur final sont transmises avec la réponse, ce qui renforce la sécurité des données protégées : en permettant l’authentification de l’utilisateur final au niveau des fournisseurs de ressources protégées, on leur permet d’adapter la réponse en fonction de son statut.

Le fait que OAuth Server by DnC propose cette méthode d’authentification ne change en rien au fait que ce serveur est entièrement compatible avec la norme OAuth 2.0.

Rappelons le fait que, très souvent (le plus souvent ?) le serveur d’autorisation et les API protégées appartiennent à la même organisation. Dans cette configuration, la façon dont le jeton d’accès est généré et vérifié est opaque pour l’utilisateur. Le cas qui nous intéresse est celui dans lequel il y a une certaine indépendance des API et du serveur d’autorisation.

Cette problématique est exposée ici dans sa généralité : Validation du jeton d’accès par une ressource protégée.

Demande de validation du jeton d’accès

Une solution est de demander au serveur d’autorisation d’authentifier le jeton d’accès. La demande est adressée par le serveur de ressource à OAuth Server by DnC sur le point d’extrémité de ressource à l’URI :

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

Le jeton est passé avec le paramètre "access_token" par l’une des méthodes suivantes : Auth Header, GET ou POST.

Une seule méthode doit être utilisée à la fois, sinon le serveur retourne ’400, invalid_request’.

Méthode Auth Header :
C’est la méthode recommandée.

Méthodes POST :
Lorsque vous placez le jeton dans le corps de la requête HTTP, la méthode doit être POST ou PUT. Sinon, le serveur retourne 400, ’invalid_request’, ’When putting the token in the body, the method must be POST or PUT’, ’#section-2.2’.

Le type de contenu pour les requêtes POST doit être "application / x-www-form-urlencoded. Si ce n’est pas le cas, le serveur retourne 400, ’invalid_request’, ’The content type for POST requests must be "application/x-www-form-urlencoded".

Méthodes GET :
Cette méthode n’est pas recommandée pour des raisons de sécurité.

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 (remarquez la présence des données relatives à l’utilisateur final) :

index type valeur
status entier code HTTP
headers string Headers de la réponse
page string JSON Array :
success : true,
client_id : ID de l’application cliente
user_id : ID de l’utilisateur final
expires : Unix Time de la fin de validité (long) (secondes depuis le 1° janvier 1970).
scope : liste des scopes de l’application cliente
id_user : ID interne de l’utilisateur final
username : ID OAuth de l’utilisateur final
given_name : prénom
middle_name : complément de nom
family_name : nom
nickname : surnom
profile : URL de la page de profil
picture : URL de la photo
website : URL du site web
email : adresse E-mail

verified : true si l’email a été vérifié
gender : male/female
birthday : date de naissance

zoneinfo : décalage horaire /UTC
locale : code langue selon RFC-3066
phone_number : numéro de téléphone
street_address, locality, region, postal_code, country : adresse
updated_time : instant de mise à jour du profil
created_time : instant de création du profil
statut : statut de l’utilisateur
maj : instant de mise à jour des données

Notes :
- Les 5 premières variables correspondent au standard OAuth. Le fait qu’il y en ait plus ne change rien au fait que OAuth Server by DnC répond parfaitement au standard.
- user_id et username ont la même valeur et correspondent à l’identifiant unique de l’utilisateur final. Le fait qu’il y ait deux variables de valeurs identiques provient d’une ambiguïté entre le standard et OAuth 2.0 Server PHP.
- les données en italiques sont transmises sous certaines conditions, en fonction de la configuration d’une application particulière.

 

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 données par le tableau suivant :

Réponse error
titre de l’erreur
error_description
description de l’erreur
Explication
400 invalid_request Only one method may be used to authenticate at a time (Auth header, GET or POST) La requête est mal formée
400 invalid_request Malformed auth header La requête de type Auth header est mal formée
400 invalid_request When putting the token in the body, the method must be POST or PUT Si on place le token dans le corps de la requête, la méthode ne peut être que POST ou PUT
400 invalid_request The content type for POST requests must be "application/x-www-form-urlencoded l’IETF spécifie ce type de contenu. NB : tous les serveurs Web ne remplissent pas cette variable _SERVER voir http://tools.ietf.org/html/rfc6750#section-2.2
401 invalid_token The access token provided is invalid le jeton ne figure pas dans le tokenStorage du serveur. Très probablement une tentative de violation d’accès.
401 expired_token The access token provided has expired Le jeton a expiré. L’application doit obtenir un nouveau jeton et relancer la requête
403 insufficient_scope The request requires higher privileges than provided by the access token Le scope (éventuellement) transmis avec la requête ne correspond pas aux scopes autorisés pour l’application.

Notes :
- Si on adresse une requête avec un jeton d’accès nul (empty string), le contrôleur ressource retourne le code HTTP 401, mais le corps de la réponse est vide, alors que l’on s’attendrait à error = ’invalid_token’. Il s’ensuit que l’on devrait traiter tous les codes HTTP 401 dont l’erreur n’est pas ’expired_token’ comme étant une tentative de violation d’accès.
- En cas de tentative de violation d’accès (code HTTP 401 et error = ’invalid_request’, le mieux est sans doute de ne rien répondre pour ne pas renseigner l’attaquant.

Exemples

Demande de validation d’un token d’accès :

SPIP

  1. /*
  2. Autorisation avec OAuth Server by DnC
  3. Auteur : Bertrand degoy
  4. Copyright (c) 2016 DnC
  5. */
  6.  
  7. function oauth_authorize($accesstoken) {
  8.  
  9. $Ok = false;
  10.  
  11. if ( !empty( $accesstoken ) ) {
  12.  
  13. // Interroger OAuth Server by DnC
  14. include_spip('inc/distant');
  15. $url = "http://oa.dnc.global/oauth/resource.php?access_token=" . $accesstoken;
  16. $resource_response = recuperer_url($url);
  17.  
  18. if ( (int)$resource_response['status'] === 200 ) {
  19. $page = json_decode($resource_response['page'], true);
  20. if ( $page['success'] == 'true' ) {
  21. if ( isset($_SERVER["HTTP_ORIGIN"]) ) {
  22. // Accès HTTP (CORS) : autoriser l'origine
  23. include_spip('inc/headers');
  24. $issuer = trim(strtr($_SERVER["HTTP_ORIGIN"], '<>"\'', '[]##'));
  25. header('Access-Control-Allow-Origin', $issuer);
  26. }
  27. $Ok = true;
  28. }
  29. }
  30.  
  31. }
  32.  
  33. return $Ok;
  34.  
  35. }

Télécharger

L’interrogation du serveur d’autorisation à chaque accès d’une ressource protégée peut le surcharger. Pour éviter cela, il est recommandé de mettre en cache la réponse du serveur du côté du serveur de ressource. Avec SPIP, c’est le rôle de la fonction recuperer_url_cache() qui pourra remplacer recuperer_url() dans l’exemple précédent. La fonction permet de régler le délai de garde en cache, qu’il convient de fixer à une durée assez courte (quelques minutes par exemple), l’essentiel étant de ne pas bombarder le serveur. Voici un exemple :

SPIP

  1. $res = recuperer_url_cache( $url, array('delai_cache' => 300) );

La fonction décrite précédemment peut être utilisée dans une fonction d’autorisation d’accès à un objet SPIP ( ici l’objet gis de radar ) :

SPIP

  1. function _autoriser_gis($faire, $quoi, $id, $qui, $options) {
  2. if ( $qui['statut'] == '0minirezo' ) {
  3. // Toujours autoriser un administrateur
  4. return true;
  5. } else {
  6. if ( $accesstoken = $_GET['token'] ) {
  7. // Vérifier le jeton d'accès
  8. return oauth_authorize($accesstoken);
  9. } else return false;
  10. }
  11. }

Télécharger

Notes :
- Dans le cas où l’application cliente et le serveur données protégées se trouvent dans des domaines différents, il faut gérer l’autorisation HTTP. Voyez Contrôle d’accès HTTP (CORS).

Introspection Endpoint

Le document RFC 7662 : OAuth 2.0 Token Introspection propose une méthode identique dans le principe et très proche dans la réalisation. Les données retournées sont au format JSON et se rapprochent du contenu d’un JSON Web Token (JWT).

OAuth Server by DnC offre donc également le point d’extrémité suivant :

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

La demande est effectuée comme pour l’appel à ’resource’, mais le paramètre est ’token’ au lieu de ’access_token’.

En cas de succès, la réponse est conforme au document précité. Les données retournées sont ’active’, ’scope’, ’client_id’, ’username’, ’exp’.

A ces données, s’ajoute ’sub’ dont la valeur est l’E-mail de l’utilisateur. Toutefois, cette donnée n’est présente que si l’E-mail de l’utilisateur a été vérifié.

En cas d’erreur, la réponse est identique à celle de ’resource’.

Notes

[1La spécification OAuth 2.0, RFC6749, aborde très précisément ce problème dans la section 7 : Les méthodes utilisées par le serveur de ressource pour valider le jeton d’accès (ainsi que toute réponse d’erreur) dépassent le cadre de cette spécification, mais impliquent généralement une interaction ou une coordination entre le serveur de ressources et le serveur d’autorisation".

Validation du jeton d’accès avec la déclaration at_hash du jeton d’identité

, par DnC

Si le jeton d’ID contient une déclaration at_hash, le client PEUT l’utiliser pour valider le jeton d’accès.

Ceci est une précaution de sécurité utile (voire indispensable ?). En effet, nous disposons de la faculté de vérifier le JWT avec sa signature, mais nous ne disposons pas de la faculté de valider un jeton d’accès de façon autonome (puisque c’est un jeton opaque).

Encore un bon point pour OpenID Connect ! Un bon point aussi pour la bibliothèque oauth2-server-php de Brent Schaffer qui insère la déclaration at_hash dans le jeton d’identité [1]. Donc un bon point aussi pour OAuthSD.

Cet article est une traduction d’extraits de OpenID Connect Core 1.0

3.1.3.8. Validation du jeton d’accès

Lors de l’utilisation du flux de code d’autorisation, si le jeton d’ID contient une déclaration at_hash, le client PEUT l’utiliser pour valider le jeton d’accès de la même manière que pour le flux implicite, tel que défini dans la section 3.2.2.9, Jeton d’accès renvoyé à partir du point d’extrémité Token.

3.2.2.9. Validation du jeton d’accès

Pour valider un jeton d’accès émis à partir du point d’extrémité d’autorisation avec un jeton d’ID, le client DOIT faire ce qui suit :

- Hash les octets de la représentation ASCII de l’access_token avec l’algorithme de hachage spécifié dans JWA [JWA] pour le paramètre Alg Header de l’en-tête JOSE de Token ID. Par exemple, si l’alg est RS256, l’algorithme de hachage utilisé est SHA-256.
- Prendre la moitié la plus à gauche du hachage et base64url encoder.
- La valeur de at_hash dans le jeton d’identification DOIT correspondre à la valeur produite à l’étape précédente.

Notes

[1A la lecture du code, il apparait que la déclaration at_hash est toujours émise, quel que soit le flux.