Obexal Docs

Docs/Démarrer/Connecter votre première app

Connecter votre première app

Déclarez une application OIDC et déroulez le flux authorization code avec PKCE de bout en bout : authorize, échange de jetons, id_token, userinfo.

Ce démarrage rapide connecte une application à Obexal avec OpenID Connect, de bout en bout : vous déclarez un client, puis vous déroulez le flux authorization code avec PKCE avec un simple curl et un navigateur. Si votre application ne parle que SAML, Obexal agit aussi comme fournisseur d'identité SAML 2.0.

Le document de découverte liste tous les endpoints utilisés ci-dessous :

curl https://accounts.obexal.com/.well-known/openid-configuration
Note

Tous les exemples utilisent accounts.obexal.com, le domaine par défaut. Si votre organisation utilise un domaine personnalisé, remplacez-le.

Déclarer l'application

Dans la console d'administration, ouvrez Applications et créez un client :

  • Nom : ce que votre équipe reconnaîtra.
  • Type : public pour une application navigateur ou mobile (sans secret, PKCE seul), confidential pour une application côté serveur (reçoit un secret client).
  • URL de redirection : les URL absolues http(s) exactes vers lesquelles l'utilisateur revient après connexion. La correspondance est une égalité stricte de chaînes, sans joker.

Pour un SaaS connu (Slack, Jira et d'autres), partez plutôt du catalogue d'intégrations : il pré-remplit la configuration et crée un client prêt à l'emploi.

Copiez le clientId (par exemple app_a1b2c3). Pour un client confidential, le clientSecret est affiché une seule fois à la création : conservez-le immédiatement, il n'est jamais réaffiché.

Préparer PKCE

PKCE est obligatoire pour tous les clients, publics comme confidentiels, et seule la méthode S256 est acceptée :

VERIFIER=$(openssl rand -base64 60 | tr '+/' '-_' | tr -d '=\n')
CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -binary -sha256 | openssl base64 | tr '+/' '-_' | tr -d '=\n')

Obtenir un code d'autorisation

Envoyez le navigateur de l'utilisateur vers /oauth/authorize (présenté ici sur plusieurs lignes pour la lisibilité) :

https://accounts.obexal.com/oauth/authorize
  ?response_type=code
  &client_id=app_a1b2c3
  &redirect_uri=https%3A%2F%2Fapp.example.eu%2Fcallback
  &scope=openid%20profile%20email
  &state=xyz
  &nonce=n0abc123
  &code_challenge=<CHALLENGE>
  &code_challenge_method=S256
  • Sans session, l'utilisateur est d'abord redirigé vers la page de connexion hébergée, se connecte, puis revient à la même URL d'autorisation.
  • En cas de succès, le navigateur est redirigé vers https://app.example.eu/callback?code=<CODE>&state=xyz.
  • scope doit inclure openid ; les scopes pris en charge sont openid, profile et email.
  • Si l'application est restreinte à des groupes, un utilisateur hors de ces groupes reçoit error=access_denied.

Échanger le code contre des jetons

Le code est à usage unique et de courte durée. Échangez-le sur /oauth/token (corps form-encoded, sans cookie, sans CSRF) :

curl -sS -X POST https://accounts.obexal.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code' \
  -d 'code=<CODE>' \
  -d 'redirect_uri=https://app.example.eu/callback' \
  -d 'client_id=app_a1b2c3' \
  -d "code_verifier=$VERIFIER"
{
  "access_token": "<JWT>",
  "token_type": "Bearer",
  "expires_in": 600,
  "refresh_token": "<opaque>",
  "id_token": "<JWT>",
  "scope": "openid profile email"
}

Un client confidential s'authentifie en plus avec son secret :

curl -sS -u "app_conf:$CLIENT_SECRET" -X POST https://accounts.obexal.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code' -d 'code=<CODE>' \
  -d 'redirect_uri=https://app.example.eu/callback' -d "code_verifier=$VERIFIER"

Rejouer le code, ou présenter un mauvais code_verifier, renvoie 400 {"error":"invalid_grant"}.

Lire l'id_token

L'id_token est un JWT signé en RS256 (seul algorithme). Vérifiez-le avec les clés publiées sur /.well-known/jwks.json, puis lisez les claims :

ClaimContenu
iss, aud, exp, iatémetteur, votre client_id, expiration, date d'émission
subidentifiant stable de l'utilisateur
auth_timedate de la connexion interactive
noncerenvoyé si vous en avez fourni un (protection anti-rejeu)
email, email_verifiedavec le scope email
given_name, family_name, name, localeavec le scope profile, quand renseignés dans l'annuaire
groupsnoms des groupes de l'utilisateur, omis si vide

Règles de vérification complètes : Valider les jetons.

Tester l'endpoint userinfo

curl -sS https://accounts.obexal.com/oauth/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "sub": "8b1e2c4a-7f3d-4e5b-9a6c-1d2e3f4a5b6c",
  "email": "alice@example.eu",
  "email_verified": true,
  "given_name": "Alice",
  "family_name": "Martin",
  "name": "Alice Martin",
  "locale": "fr"
}

Les claims suivent les scopes portés par l'access token ; un jeton absent, invalide ou expiré renvoie 401.

Limites et prochaines étapes

  • response_type=code uniquement : pas de flux implicit ni hybrid.
  • PKCE en S256 est exigé ; plain est refusé.
  • Les jetons sont signés en RS256 uniquement.
  • Les refresh tokens tournent à chaque usage ; réutiliser un ancien révoque toute la chaîne.

Poursuivez avec OIDC et OAuth 2.1 en profondeur, sessions et déconnexion et, pour les clients durcis, PAR, DPoP et private_key_jwt.