Comment implémenter le WebID dans le SSO?

Ce sujet fait suite à Une alternative temporaire à WebID-OIDC? pour continuer les échanges avec @srosset et @simon.louvet.zen.

Depuis le frontend d’un SemApps, comment permettre l’affichage de ressources situées sur un autre SemApps de manière authentifiée (via un même SSO) ?

SSOWebIDProb

Nous avons pensé à l’idée de stocker le WebID de l’utilisateur dans le SSO commun aux deux SemApps. Actuellement, la normalisation du stockage du WebID est partagée entre plusieurs normes concurrentes. Pour le moment SemApps préfère l’implémenter d’une manière temporaire en attendant d’adopter une norme.

Mais alors comment mettre en œuvre ce stockage temporaire du WebID dans le SSO ?

Scenario 1 : utilisation normale de l’access_token

  1. L’utilisateur s’identifie sur le SemApps1.
  2. Frontend1 reçoit un id_token et un access_token de lecture;
  3. Fontend1 demande la ressource à SemApps2 en fournissant l’access_token de lecture;
  4. SemApps2 vérifie ce token et récupère son WebID associé via le userinfo endpoint du SSO;
  5. SemApps2 vérifie les ACL et renvoie la ressource correspondant au WebID récupéré précédemment à Frontend1.

En sachant qu’un mécanisme de cache peut être positionné sur l’étape 4.

Scenario 2 : utilisation détournée de l’id_token

  1. L’utilisateur s’identifie sur le SemApps1.
  2. SemApps1 reçoit un id_token contenant le WebID;
  3. Fontend1 demande la ressource à SemApps2 en fournissant l’id_token;
  4. SemApps2 vérifie l’id_token et les ACL;
  5. SemApps2 renvoie la ressource correspondant au WebID (dans l’id_token) à Frontend1.

Scenario 3 : utilisation simplifiée de l’access_token

  1. L’utilisateur s’identifie sur le SemApps1.
  2. SemApps1 reçoit un id_token et Frontend1 reçoit un access_token de lecture contenant le WebID de l’utilisateur;
  3. Fontend1 demande la ressource à SemApps2 en fournissant l’access_token de lecture;
  4. SemApps2 vérifie l’access_token et les ACL;
  5. SemApps2 renvoie la ressource correspondant au WebID (dans l’access_token) à Frontend1.

D’après moi le scenario 1 est celui qui respecte le « mieux » la norme OIDC en séparant bien l’id_token de l’access_token. En effet, l’id_token n’est pas sensé être utilisé pour demander l’accès à une ressource mais pour identifier un utilisateur. Imaginez qu’un SemApps2 malicieux pourrait utiliser cet id_token pour agir en tant que l’utilisateur de façon malveillante. Alors qu’avec seulement un access_token de lecture en main ce serveur malicieux ne pourrait pas faire grand chose à part lire des données.

Le scenario 3 simplifie les choses mais contredit le rôle de l’access_token qui est d’autoriser et pas d’identifier. Cependant, une récente RFC, indique qu’il est possible de mettre des infos d’identification dans un access_token dans le cas où l’on requête son propre backend (ce qui n’est pas le cas ici) :

This is particularly common in scenarios where the client and the resource server belong to the same entity and are part of the same solution, as is the case for first-party clients invoking their own backend API.

Nous devons également faire face à un autre problème de taille : l’API de modification des user_claims du SSO (attributs utilisateur) est accessible avec un simple access_token. Cela signifie qu’un utilisateur pourrait modifier son WebID lui-même dans le SSO et donc se faire passer pour quelqu’un d’autre !

1 « J'aime »

Je partage ta conclusion dans l’absolue. Cependant, la frontière entre accès à une ressource et identification est plus poreuse en LDP/web sémantique que dans le web « classique ». Il n’y a pas de service qui ne soit une ressource. Il est biensur possible de rajouter des services métier dans semapps en plus de LDP. Il y également qqc qui me pose encore question pour utiliser l’acces_token. L’acces token est généralement délivré quand une application externe souhaite accéder à une ressource. Les scope délivré par le serveur sso dépend de l’application qui demande le token. Dans notre cas du frontend1 ou du semapps 1 qui demande au semapps2 d’accéder à une ressource, cela voudrait dre que le frontend1 ou semapps1 demande au serveur SSO d’accéder à une ressource du semapps2 et que le tocke délivré (ses scopes) ne correspondent qu’aux semapps2 et ne peut pas être utilisé pour accéder aux données du semapps3. Je me demande encore une fois si c’est pas de l’ overengineering.

1 « J'aime »

Merci @lecoqlibre pour ces clarifications !

Perso je serais plutôt partant pour le scénario 1, par contre je ne vois pas en quoi il est plus sécurisé que le scénario 2. En effet, si SemApps2 reçoit l’access_token, qu’est-ce qui l’empêche de l’utiliser pour aller récupérer toutes les données de l’utilisateurs sur SemApps1 ? (ou sur toute autre instance existante) On n’est pas à l’abri d’un usage malicieux.

Il me semble que s’il y avait un access_token par serveur, on pourrait limiter ces abus: l’access_token2 envoyé à SemApps2 ne serait utilisable que sur le serveur SemApps2, mais pas sur le serveur SemApps1. Est-ce que ce serait possible ?

A moins que le fait que SemApps2 puisse aller récupérer des données sur SemApps1 soit une feature désirée… ?

C’est un gros problème en effet. :hushed: Il faudrait qu’au moment du login, SemApps1 vérifie que le webId reçu correspond bien à celui qui est dans son triple store, en le mettant en relation avec un UUID ou autre chose (Actuellement le SSO renvoie pas mal de données qui permettent d’identifier uniquement l’utilisateur.) Et si ce n’est pas le cas, le webId serait ignoré, ou l’utilisateur ne serait pas connecté.