À propos de la nécessité pour le Serveur de Ressource de s’authentifier
Selon rfc7662 Section 2.1. :
"L’appelant DOIT avoir une autorisation pour accéder à ce point de terminaison".
(Ce que nous aurions pu faire pour se conformer à cette spécification :
Cette implémentation attend un jeton d’accès émis pour un client enregistré (non public).
La provenance de ce jeton d’accès dépend du service.
Il a peut-être été obtenu du serveur d’autorisation par l’appelant en tant qu’application cliente.
Ou bien, si l’appelant est un serveur de ressources interrogé par une application cliente, le jeton lui a peut-être été transmise par l’appelant.)
Nous soumettons à la sagacité du lecteur les observations suivantes :
Le but de cette autorisation est "Pour empêcher les attaques par balayage de jetons".
Ce type d’attaques est généralement géré au niveau du pare-feu en relation avec le service.
Par exemple, avec Apache, nous pourrions définir une authentification HTTP Basic au niveau du répertoire.
Ensuite, sur un serveur géré WHM / cPanel, nous pourrions utiliser CSF / LFD pour bloquer les échecs de connexion répétitifs.
Nous pourrions également configurer à cette fin une règle Apache Modsec particulière.
Plus généralement, l’attenuation des attaques est mieux effectuée en amont plutôt qu’au niveau de l’application. Cela induit une charge de calcul moindre, voire nulle, sur le serveur d’autorisations.
Pour que le serveur de ressources s’authentifie, il doit être enregistré en tant qu’application cliente [1], ce qui suppose qu’il appartient au domaine de l’entreprise.
Ceci est vrai dans la plupart des cas, mais nous pouvons désirer que tout serveur de ressources étranger puisse vérifier un JWT.
À propos du but de l’Introspection
Valider la signature
La charge utile du jeton JWT n’est pas cryptée, seulement encodée. Son contenu est immédiatement lisible par le RS avant la validation de la signature.
Donc, le RS a besoin d’une introspection pour vérifier que la signature est valide (si elle ne la valide pas localement en utilisant la clé publique).
Authentifier l’application qui appelle le serveur de ressource (RS)
De plus, le but de transmettre un jeton à un RS est de lui indiquer s’il peut répondre à l’application requérante et quelles données il peut lui transmettre dans sa réponse.
Un attaquant pourrait avoir volé un JWT et l’utiliser avec sa propre application. Le risque est que le RS réponde à une application et / ou à un utilisateur non autorisé. Il est donc essentiel d’authentifier l’application qui interroge le RS pour l’empêcher de répondre à un malware (voir plus loin).
Cela dit, quelle tâche spécifique doit être accomplie par l’Introspection et quelle doit être la réponse ?
À propos de la réponse de l’Introspection
Selon la section 2.2. de rfc7662, le seul membre requis est "actif", un indicateur booléen indiquant la validité du jeton vu depuis le serveur qui l’a émis.
Cela va au-delà de la validation de la signature car cela "indique qu’un jeton donné a été émis par ce serveur d’autorisation, n’a pas été révoqué par le propriétaire de la ressource, ...".
Mais inclure dans cette valeur la condition "et se trouve dans sa fenêtre temporelle de validité donnée" ne parait pas pertinent : le RS possède déjà les informations de la charge utile. En revanche, le jeton pourrait avoir été invalidé au niveau du serveur, et c’est cette information que l’introspection apportera. Au passage, notons qu’il n’y a pas de lien entre la durée de vie du jeton d’accès et celle du jeton d’identité. Il y a une possibilité de révoquer le jeton d’accès, mais qu’en est-il du jeton d’identité ?
Notez que l’Introspection devrait également être utilisable pour valider un jeton d’accès JWT, avec des membres moins nombreux et différents. C’est une autre raison pour ne pas spécifier les membres de façon autoritaire.
Empêcher le Serveur de Ressource de répondre à un malware
C’est une question centrale !
La spécification reconnaît la question, mais ne donne pas une réponse normalisée. Il est indiqué dans la section 2.1 :
"Le point de terminaison d’introspection PEUT accepter d’autres paramètres OPTIONNELS pour fournir un contexte supplémentaire à la requête. Par exemple, un serveur d’autorisation peut souhaiter connaître l’adresse IP du client accédant à la ressource protégée pour déterminer si le client présentant le jeton est le bon. La définition de ce paramètre ou de tout autre paramètre sort du cadre de la présente spécification, ... "
Nous proposons mettre ceci en œuvre de la manière suivante :
Si le RS appelant le point de terminaison Introspection transmet l’adresse IP de son propre demandeur dans le ’requester_ip’, nous devons vérifier que cette adresse IP se trouve dans le même sous-réseau que l’application cliente identifiée par la déclaration ’aud’. Voyez : Vérification de l’origine de la requête reçue par un serveur de ressource.
À propos de l’adaptation de la réponse au Serveur de Ressource
Il est indiqué à la section 2.2 :
"Le serveur d’autorisation PEUT répondre différemment à différentes ressources protégées qui font la même demande. Par exemple, un serveur d’autorisation PEUT limiter les étendues d’un jeton donné qui sont renvoyées à chaque ressource protégée afin d’empêcher une ressource protégée d’en apprendre davantage sur l’ensemble plus vaste d’applications du réseau que nécessaire pour son fonctionnement. "
Cela semble très difficile à mettre en œuvre. Dans l’exemple donné, qui traite des portées, le RS doit faire appel à l’introspection avec plus de paramètres ou le AS doit avoir des informations sur le RS. En somme, il s’agit de prendre en compte les scopes au niveau de l’introspection pour définir les autorisations.
Cette prescription peut être appliquée dans un domaine d’entreprise pour des applications particulières, elle ne sera donc pas prise en compte dans notre "implémentation minimale et compatible".
Nous pensons que les portées définissant les droits ont une signification qui devrait être interprétée par la ressource protégée elle-même, le serveur d’authentification devant les transmettre de manière transparente. Voyez : Incorporer au jeton JWT des déclarations supplémentaires.
... ou ne répond pas du tout
Il est indiqué dans la section 4 :
"Si le jeton ne peut être utilisé que sur certains serveurs de ressources, le serveur d’autorisation DOIT déterminer s’il peut ou non être utilisé sur le serveur de ressources effectuant l’appel d’introspection".
Cette prescription n’est rien de plus qu’une déclinaison radicale de la précédente. Nous allons la traiter de la même manière.
Proposition d’un contrôleur d’introspection pour la bibliothèque
Une "implémentation minimale et compatible" du contrôleur Introspection aurait les caractéristiques suivantes :
se limitera à la validation de la signature JWT avec l’option de vérification de l’adresse IP du client (paramètre ’requester_ip’), sans aucune hypothèse quant à l’utilisation du jeton,
ne nécessitera pas l’authentification de l’appelant,
acceptera le jeton porteur de préférence pour poster un jeton,
peut répondre comme indiqué dans le RFC.
Suivez ce développement sur GitHub
Voyez le fork :
https://github.com/bdegoy/oauth2-server-php
Testez avec :
https://github.com/bdegoy/oauth2-server-php-introspection-test
Discutez-en :
https://github.com/bshaffer/oauth2-server-php/pull/964