Passer au contenu principal

OAuth Steam et OAuth Telegram avec Casdoor : Ajouter des connexions sociales non standards via OIDC

· Lecture de 11 minutes
Yang Luo
Casdoor Maintainer

Il n'existe pas d'« OAuth Steam » : Steam authentifie les utilisateurs avec OpenID 2.0 et vous fournit un SteamID 64 bits, rien de plus. Le widget de connexion classique de Telegram n'est pas non plus de l'OAuth : il transmet à votre page un ensemble de champs utilisateur ainsi qu'un hash HMAC-SHA256 que vous vérifiez avec votre token de bot. Telegram propose désormais également un véritable fournisseur OpenID Connect sur oauth.telegram.org. Si vous placez Casdoor entre votre application et ces fournisseurs, Casdoor effectue les vérifications spécifiques au protocole et votre application ne parle que OpenID Connect à Casdoor, de la même manière que pour Google ou GitHub.

Aperçu des fournisseurs​

FournisseurProtocoleCe qui identifie l'utilisateurEmail disponible ?Type de fournisseur Casdoor
SteamOpenID 2.0 sur https://steamcommunity.com/openid/login, plus l'API Web Steam pour le profilSteamID64, extrait de l'ID revendiqué https://steamcommunity.com/openid/id/<steamid>NonSteam
Telegram (Widget de connexion)Données signées du widget, HMAC-SHA256 clé avec le SHA-256 du token de botid de l'utilisateur TelegramNonTelegram
Telegram (OpenID Connect)Flux de code d'autorisation OIDC avec PKCE sur https://oauth.telegram.orgClaim sub du jeton d'IDPas de claim email ; téléphone avec le scope phoneCustom
X (Twitter)Code d'autorisation OAuth 2.0 avec PKCEID utilisateur X obtenu via /2/users/meNon avec les scopes par défaut de CasdoorTwitter
FacebookCode d'autorisation OAuth 2.0ID utilisateur limité à l'applicationUniquement si le profil possède un email primaire valideFacebook

Le reste de cet article détaille ce que chaque protocole retourne réellement et ce que Casdoor en fait.

Steam : OpenID 2.0, pas d'OAuth​

Les pages développeurs de Steam décrivent Steam comme un fournisseur OpenID : votre site redirige l'utilisateur vers Steam, et Steam renvoie un ID revendiqué sous la forme https://steamcommunity.com/openid/id/<steamid>. Le nombre final est le SteamID 64 bits de l'utilisateur. Il n'y a pas de code d'autorisation, pas de jeton d'accès, pas de scopes, et pas d'email : ni la réponse OpenID ni le profil API Web n'en contiennent.

C'est pourquoi les recherches pour « steam oauth » ne mènent nulle part d'utile : le protocole est OpenID 2.0, le prédécesseur d'OpenID Connect, donc une bibliothèque cliente OAuth 2.0 ou OIDC ne peut pas communiquer directement avec Steam.

Ce que fait Casdoor pour une connexion Steam :

  1. La page de connexion Casdoor construit une requête OpenID 2.0 checkid_setup vers https://steamcommunity.com/openid/login, avec openid.realm défini sur l'origine Casdoor et openid.return_to défini sur la page /callback de Casdoor.
  2. Lorsque Steam redirige en arrière, Casdoor poste les champs signés à nouveau vers Steam avec openid.mode=check_authentication. Ce n'est que si Steam répond is_valid:true que le processus continue. Il vérifie également que openid.claimed_id correspond au motif steamcommunity.com/openid/id/<digits> et en extrait le SteamID.
  3. Avec la clé API Web Steam que vous saisissez comme Client secret du fournisseur, Casdoor appelle ISteamUser/GetPlayerSummaries pour obtenir le nom d'affichage (persona name) et l'avatar.

L'utilisateur Casdoor résultant utilise le SteamID64 comme nom d'utilisateur, le pseudonyme Steam comme nom affiché et l'avatar Steam. Le champ e-mail reste vide. Casdoor supprime intentionnellement le texte de substitution que la bibliothèque sous-jacente y place. Si votre application a besoin d'une adresse e-mail, collectez-la après l'inscription.

La configuration prend deux minutes : enregistrez une clé API Web pour votre domaine Casdoor sur la page des clés de Steam, créez un fournisseur de type Steam et collez la clé comme secret client. Le guide du fournisseur Steam détaille les étapes.

Telegram : le widget de connexion et sa vérification HMAC​

La connexion classique à Telegram est un widget JavaScript. Vous créez un bot avec @BotFather, liez votre domaine à celui-ci via /setdomain, et intégrez le widget. Lorsque l'utilisateur confirme dans Telegram, le widget redirige soit vers l'URL spécifiée dans data-auth-url, soit appelle une fonction JavaScript, en passant id, first_name, last_name, username, photo_url, auth_date et hash.

Aucun élément de cette charge utile n'est un jeton. N'importe qui peut saisir ces champs dans une URL, donc le serveur doit vérifier le hash. La vérification documentée par Telegram fonctionne comme suit :

data_check_string = all received fields except hash,
as key=value, sorted by key, joined with "\n"
secret_key = SHA256(bot_token)
valid = hex(HMAC_SHA256(data_check_string, secret_key)) == hash

Telegram vous conseille également de vérifier auth_date afin que les données anciennes ne puissent pas être rejouées, mais laisse la durée de validité à votre discrétion.

Dans Casdoor, le type de fournisseur Telegram prend le nom d'utilisateur du bot (sans @) comme Client ID et le token du bot comme Client secret. Lorsqu'un utilisateur clique sur le bouton Telegram, Casdoor ouvre sa propre page /telegram-login, qui charge telegram-widget.js depuis telegram.org avec le nom d'utilisateur de votre bot et dirige data-auth-url vers le /callback de Casdoor. Le callback collecte les champs et le backend Casdoor effectue ensuite :

  • reconstruit la chaîne de vérification des données à partir de chaque champ sauf hash, la trie, et compare le HMAC-SHA256 au hash en utilisant SHA256(bot token) comme clé ;
  • rejette les données si auth_date date de plus de 24 heures ;
  • utilise l'id numérique de Telegram comme identité, le username comme nom d'utilisateur, le prénom et le nom comme nom affiché, et photo_url comme avatar.

Les noms d'utilisateur Telegram sont optionnels. Lorsqu'un utilisateur n'en a aucun, Casdoor génère telegram_<id>, qui reste le même à chaque connexion. Le widget n'envoie jamais d'adresse e-mail ni de numéro de téléphone, donc un utilisateur Telegram uniquement dans Casdoor n'a ni l'un ni l'autre. Voir le guide du fournisseur Telegram pour les étapes BotFather.

Telegram propose désormais aussi OpenID Connect​

La page "Log In With Telegram" de Telegram documente désormais un flux OpenID Connect standard, et l'ancienne documentation du widget iframe a été déplacée vers une page d'archive. Les faits issus de la documentation de Telegram :

  • Document de découverte : https://oauth.telegram.org/.well-known/openid-configuration. Point de terminaison d'autorisation https://oauth.telegram.org/auth, point de terminaison de jeton https://oauth.telegram.org/token, clés disponibles sur https://oauth.telegram.org/.well-known/jwks.json.
  • Dans @BotFather, ouvrez les paramètres du Login Widget de votre bot, enregistrez les URLs autorisées (origines et URIs de redirection exactes), et obtenez un identifiant client et un secret client.
  • Flux de code d'autorisation, PKCE avec S256 recommandé. La demande de jeton utilise l'authentification HTTP Basic avec l'identifiant client et le secret.
  • Portées (scopes) : openid est obligatoire ; profile ajoute le nom, preferred_username et picture ; phone ajoute phone_number avec le consentement de l'utilisateur. Il n'y a pas de claim e-mail.
  • Il n'y a pas de point de terminaison UserInfo. Toutes les données utilisateur se trouvent dans le jeton d'identification (ID token), dont l'iss est https://oauth.telegram.org et dont l'aud est l'ID de votre bot.

Vous pouvez connecter ce flux avec un fournisseur OAuth personnalisé Casdoor. Définissez l'Auth URL et la Token URL sur les points de terminaison ci-dessus, définissez la Scope sur openid profile (ajoutez phone si nécessaire), activez Enable PKCE, et laissez l'UserInfo URL vide. Enregistrez le https://<your-casdoor-host>/callback de Casdoor comme URL autorisée dans BotFather. Sans URL UserInfo, Casdoor extrait l'utilisateur du jeton d'identification dans la réponse du jeton : il exige sub, rejette un jeton expiré, et vérifie que aud contient l'identifiant client. Sans mappage utilisateur, sub devient l'ID utilisateur, preferred_username le nom d'utilisateur, name le nom affiché et picture l'avatar, et phone_number remplit le téléphone. La page de connexion Casdoor reconnaît un fournisseur personnalisé dont l'URL d'autorisation pointe vers oauth.telegram.org et maintient court l'state OAuth pour celui-ci.

Notez qu'un utilisateur Telegram connecté via le widget et la même personne connectée via OIDC ne sont pas automatiquement le même utilisateur Casdoor. L'identité du widget est l'id numérique, tandis que l'identité OIDC est sub, et les exemples de Telegram eux-mêmes montrent des valeurs différentes pour les deux. Choisissez une méthode par application.

X (Twitter) et Facebook​

Ce sont deux fournisseurs OAuth 2.0 ordinaires, mais chacun a un détail important à connaître.

X exige un défi PKCE sur son URL d'autorisation OAuth 2.0. Le type Twitter de Casdoor génère un nouveau vérificateur de code pour chaque connexion, envoie le défi S256, et passe le vérificateur lors de l'échange de jetons, donc il n'y a rien à configurer au-delà de l'identifiant client et du secret. Casdoor demande les portées users.read tweet.read et lit l'utilisateur depuis /2/users/me, ce qui donne l'ID utilisateur, le handle et le nom affiché. Il ne demande pas de champ e-mail, donc prévoyez des utilisateurs X sans adresse e-mail. Le guide du fournisseur Twitter couvre les paramètres de l'application.

Facebook renvoie un ID utilisateur spécifique à l'application : la même personne a un ID différent dans chaque application Facebook, donc passer à une nouvelle application Facebook signifie que vos utilisateurs ne correspondront pas à leurs anciens enregistrements à moins que vous ne les reliiez par e-mail. Casdoor demande email,public_profile et lit id, name, picture et email depuis l'API Graph. Facebook omet email lorsque le profil n'a pas d'adresse valide. Voir le guide du fournisseur Facebook.

Comment votre application voit tout cela : OIDC simple​

Votre application ne communique jamais directement avec Steam, Telegram, X ou Facebook. Elle est un client OIDC de Casdoor, configuré une seule fois avec l'émetteur de Casdoor, https://<your-casdoor-host>/.well-known/openid-configuration. Vous ajoutez les fournisseurs sociaux à l'application Casdoor dans son onglet Providers, et leurs boutons apparaissent sur la page de connexion de Casdoor.

Après n'importe laquelle de ces connexions, Casdoor trouve ou crée un utilisateur Casdoor et termine le flux normal d'autorisation par code avec votre application. Le jeton ID que reçoit votre application est signé par Casdoor, et son champ sub est l'ID de l'utilisateur Casdoor, et non le SteamID ou l'ID Telegram. Ainsi, votre application n'a besoin d'aucune bibliothèque OpenID 2.0, d'aucun code HMAC, d'aucune particularité PKCE par fournisseur, ni de cas particulier pour les utilisateurs sans adresse e-mail. L'identifiant du fournisseur d'origine est stocké sur l'utilisateur Casdoor, par exemple dans le champ steam ou telegram, si vous en avez besoin ultérieurement.

Quelques points à prévoir :

  • Liaison de compte. Casdoor lie une connexion sociale à un utilisateur existant via l'e-mail vérifié, le téléphone vérifié ou le nom d'utilisateur, selon l'ordre défini par la règle de liaison de l'application. Steam et le widget Telegram basés sur OpenID ne fournissent ni e-mail ni téléphone, ils créent donc un utilisateur distinct sauf si l'utilisateur lie le fournisseur depuis un compte déjà connecté. Voir comment Casdoor lie les comptes.
  • Champs de profil supplémentaires. Les fournisseurs qui transmettent des données brutes, tels que le type Steam basé sur Goth et les fournisseurs personnalisés, peuvent remplir davantage de champs utilisateur via le mappage utilisateur.
  • Le côté client. Toute bibliothèque standard fonctionne avec Casdoor. Connecter un client OIDC standard liste les endpoints, et l'article SSO Spring Boot avec OIDC montre une application complète.

Références​