Aller au contenu principal

Le SSO avec kuploy-hub

kuploy-hub fait aussi office de fournisseur d'identité OpenID Connect pour les produits maison — leeram-business aujourd'hui, kuploy-cloud après migration. La connexion à ces produits redirige vers kuploy.app, l'utilisateur s'authentifie une fois, et le consommateur se fie à la session du centre par un OIDC standard.

Cette page s'adresse aux exploitants qui enregistrent un produit en aval comme client SSO de kuploy-hub. Pour la sémantique des revendications et les tournures de code côté consommateur, voir Les revendications OIDC personnalisées.

Ce qu'il vous faut​

  • kuploy-hub en service, joignable à une URL stable — https://kuploy.app, par exemple.
  • Un produit consommateur qui utilise le greffon genericOAuth de Better Auth. leeram-business en est l'implémentation de référence.

Étape 1 — Enregistrer le client de confiance sur le centre​

Les clients de confiance sont amorcés depuis la variable d'environnement KUPLOY_OIDC_TRUSTED_CLIENTS du centre. Un tableau JSON, une entrée par consommateur :

KUPLOY_OIDC_TRUSTED_CLIENTS='[
{
"clientId": "leeram-business",
"clientSecret": "<généré ; identique côté consommateur>",
"name": "Leeram Business",
"redirectUrls": [
"https://business.example.com/api/auth/oauth2/callback/kuploy",
"https://business.example.com/"
],
"skipConsent": true
}
]'

redirectUrls est validé pour deux destinations distinctes :

  • Le rappel OAuth — là où le centre renvoie le code d'autorisation après la connexion. Son chemin dépend de la version de Better Auth du consommateur, et s'y tromper est la façon la plus courante d'échouer ici :

    consommateurchemin de rappel
    Better Auth < 1.7 (leeram-business, par exemple).../api/auth/oauth2/callback/<providerId>
    Better Auth >= 1.7 (growthops, par exemple).../api/auth/callback/<providerId>

    Le greffon generic-oauth exposait autrefois son propre point d'accès de rappel ; depuis la 1.7, il enregistre ses prestataires sur la route callback/:id du cœur — ses propres sources disent « aucun point d'accès propre au greffon n'est nécessaire ». Recopier l'entrée d'un client plus ancien produit donc un redirect_uri_mismatch, qui se lit comme un mauvais secret de client, sans en être un. Vérifiez la version de better-auth du consommateur avant d'enregistrer.

  • La redirection après déconnexion — la page d'accueil du consommateur, par exemple : là où le centre renvoie le navigateur après une déconnexion à l'initiative du client. Les deux doivent figurer dans redirectUrls, sans quoi endsession rejette la demande avec invalid_request.

skipConsent: true convient à des clients maison, puisque vous possédez les deux bouts. Laissez-le à faux pour tout consommateur SSO tiers.

Après avoir modifié la variable d'environnement, redéployez le centre, pour qu'il reprenne la nouvelle liste de clients.

Étape 2 — Configurer le consommateur​

Définissez ceci sur le déploiement consommateur — leeram-business, dans cet exemple :

KUPLOY_HUB_URL=https://kuploy.app
KUPLOY_OIDC_CLIENT_ID=leeram-business
KUPLOY_OIDC_CLIENT_SECRET=<la même valeur que détient le centre>
NEXT_PUBLIC_APP_URL=https://business.example.com

La configuration Better Auth du consommateur demande les portées standard, plus offline_access, pour qu'un refresh_token soit émis à la connexion — il est nécessaire aux récupérations userinfo en direct ultérieures, ainsi qu'à la vérification de l'exploitant en direct :

genericOAuth({
config: [{
providerId: "kuploy",
discoveryUrl: `${KUPLOY_HUB_URL}/api/auth/.well-known/openid-configuration`,
clientId: KUPLOY_OIDC_CLIENT_ID,
clientSecret: KUPLOY_OIDC_CLIENT_SECRET,
scopes: ["openid", "profile", "email", "offline_access"],
pkce: true, // l'oidcProvider de kuploy-hub a requirePKCE: true
}],
}),

Étape 3 — Vérifier l'aller-retour​

  1. Connectez-vous sur le consommateur, par le bouton « Continue with Kuploy ».
  2. Vous devez être redirigé vers ${KUPLOY_HUB_URL}/sign-in, vous authentifier — ou passer sans encombre si vous l'êtes déjà —, puis revenir sur le consommateur avec une session active.
  3. Sur le consommateur, Sign Out déclenche une déconnexion à l'initiative du client : le navigateur est envoyé sur ${KUPLOY_HUB_URL}/api/auth/oauth2/endsession, le centre efface sa propre session, et l'utilisateur aboutit sur la page d'accueil du consommateur.

Le comportement à la déconnexion​

Une déconnexion locale sur le consommateur ne tue que le cookie de session de celui-ci. La session du centre, sur kuploy.app, vit sur un autre domaine et n'est pas touchée : un « Continue with Kuploy » ultérieur réauthentifie donc silencieusement contre la session de centre toujours active, et l'utilisateur est de retour dans le consommateur en 200 ms environ. C'est le défaut que corrige la déconnexion à l'initiative du client.

Le parcours de déconnexion du consommateur fait, dans cet ordre :

  1. il lit l'idToken stocké de l'utilisateur, depuis la ligne account kuploy — Better Auth le conserve après la danse OAuth ;

  2. il appelle auth.api.signOut(...) pour effacer la session locale et son cookie ;

  3. il redirige le navigateur vers :

    ${KUPLOY_HUB_URL}/api/auth/oauth2/endsession
    ?client_id=${KUPLOY_OIDC_CLIENT_ID}
    &id_token_hint=<idToken>
    &post_logout_redirect_uri=${NEXT_PUBLIC_APP_URL}/

    client_id est obligatoire : les id_token expirent au bout d'une heure environ, alors qu'une session de consommateur peut durer bien plus longtemps — l'idToken stocké peut donc être expiré au moment où l'utilisateur clique sur Sign Out. Avec client_id présent, le centre valide post_logout_redirect_uri contre les redirectUrls du client de confiance, même lorsque l'indice ne peut pas être vérifié.

  4. Le centre supprime sa propre ligne de session, efface le cookie de session de kuploy.app, et renvoie un 302 vers post_logout_redirect_uri.

Après quoi, les deux pots à cookies sont vides. Un « Continue with Kuploy » ultérieur exige réellement de saisir à nouveau ses identifiants.

L'autorité de l'exploitant sur les produits consommateurs​

Un produit consommateur reconnaît comme exploitant de son déploiement le propriétaire de l'exploitant auquel sa licence appartient, au travers de la revendication OIDC is_tenant_owner_of. leeram-business s'en sert pour garder les actions de gestion de licence (requireInstanceAdmin) : il déduit l'exploitant de la charge utile de la licence, puis vérifie que la revendication de l'utilisateur connecté le contient.

L'équipe de la plateforme Kuploy relève d'une revendication distincte (kuploy_hub_admin), qui n'en est pas un sur-ensemble : un membre de l'équipe qui ne possède pas votre exploitant n'a aucun pouvoir d'exploitant sur votre déploiement, et vous n'avez besoin d'aucun rôle d'équipe pour exploiter le vôtre.

Retirer la propriété d'un exploitant prend effet sur tous les consommateurs dans la durée de vie du jeton d'accès — une heure environ : le consommateur récupère la revendication en direct à chaque évaluation de sa garde, plutôt que de la mettre en cache.

Dépannage​

invalid_request: client_id is required when using post_logout_redirect_uri without a valid id_token_hint​

Le centre n'a pas pu vérifier id_token_hint — le plus souvent parce que le jeton stocké a expiré — et aucun client_id explicite n'a été fourni. Assurez-vous que le consommateur envoie bien client_id, en plus de id_token_hint, sur l'URL endsession — voir Le comportement à la déconnexion.

invalid_request: post_logout_redirect_uri is not registered for this client​

Ajoutez l'URL de retour après déconnexion — https://business.example.com/, par exemple — au tableau redirectUrls du client de confiance, dans KUPLOY_OIDC_TRUSTED_CLIENTS, puis redéployez le centre.

error=account_not_linked après une connexion Kuploy réussie​

Le consommateur a refusé de rattacher le compte OAuth à un utilisateur local préexistant — le comportement par défaut de Better Auth. Définissez account.accountLinking.trustedProviders: ["kuploy"] dans la configuration betterAuth({...}) du consommateur : c'est sans danger, Kuploy étant la source d'identité que vous maîtrisez.

« Continue with Kuploy » fait un aller-retour silencieux — l'utilisateur est connecté instantanément​

C'est le cookie de session du centre, toujours valide. Pour forcer une réauthentification à des fins d'essai, déconnectez-vous directement de kuploy.app — ou effacez les cookies de ce domaine —, puis réessayez. En usage normal, la déconnexion à l'initiative du client s'en occupe automatiquement.