Skip to content
Developer docs
Menu

Get started

Quickstart

Sign a person in with the authorization code flow and PKCE, step by step.

This walkthrough signs a person in to a server-side web app with the authorization code flow and PKCE. It uses example-app as the client ID and https://app.example.com/callback as the redirect URI; use your own registered values.

Before you start

  • A registered application with a client_id and at least one redirect URI. See Request access.
  • For a server-side app, its client secret, kept in your secret manager. Browser and mobile apps are registered as public clients and have no secret.
  • An OpenID Connect library, configured with the issuer https://sso.aldelo.com.

1. Discover the endpoints

Fetch the discovery document once at startup and cache it. It lists every endpoint and capability:

HTTP
GET https://sso.aldelo.com/.well-known/openid-configuration
JSON
{
  "acr_values_supported": [
    "urn:aldelo:sso:acr:pwd",
    "urn:aldelo:sso:acr:mfa",
    "urn:aldelo:sso:acr:phone"
  ],
  "authorization_endpoint": "https://sso.aldelo.com/authorize",
  "backchannel_logout_session_supported": true,
  "backchannel_logout_supported": true,
  "claims_supported": [
    "sub",
    "iss",
    "aud",
    "exp",
    "iat",
    "auth_time",
    "amr",
    "acr",
    "sid",
    "organization_id",
    "email",
    "email_verified"
  ],
  "code_challenge_methods_supported": [
    "S256"
  ],
  "end_session_endpoint": "https://sso.aldelo.com/logout",
  "grant_types_supported": [
    "authorization_code"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "introspection_endpoint": "https://sso.aldelo.com/oauth2/introspect",
  "issuer": "https://sso.aldelo.com",
  "jwks_uri": "https://sso.aldelo.com/.well-known/jwks.json",
  "prompt_values_supported": [
    "none",
    "login",
    "select_account"
  ],
  "response_types_supported": [
    "code"
  ],
  "revocation_endpoint": "https://sso.aldelo.com/oauth2/revoke",
  "subject_types_supported": [
    "public"
  ],
  "token_endpoint": "https://sso.aldelo.com/oauth2/token",
  "userinfo_endpoint": "https://sso.aldelo.com/userinfo"
}

2. Create a PKCE pair

Every sign-in uses PKCE with the S256 method. For each sign-in, generate a random code_verifier as RFC 7636 describes, and send its SHA-256 hash, base64url-encoded without padding, as the code_challenge. Keep the verifier until the callback.

Text
code_verifier  = dBjftJeZ4CVP-mJ92K1uhbDQpBqQ9cHqLhmlUA8OTkY
code_challenge = E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM

3. Send the person to sign in

Redirect the browser to the authorization endpoint:

HTTP
GET https://sso.aldelo.com/authorize
  ?response_type=code
  &client_id=example-app
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &scope=openid%20email
  &state=af0ifjsldkj-state
  &nonce=n-0S6_WzA2Mj
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

Required parameters:

  • response_type=code, the only response type.
  • client_id and redirect_uri. The redirect URI must match a registered one exactly.
  • scope: a space-separated subset of the scopes your app is registered for, from email, openid, profile. Include openid to get an ID token.
  • state: a random value of at least 8 bytes. Check that the callback returns the same value.
  • code_challenge and code_challenge_method=S256.

Optional parameters:

  • nonce (recommended): 8 to 512 bytes. It comes back in the ID token so you can tie the token to this request.
  • prompt: one or more of none, login, select_account, space-separated. none must be sent on its own: it signs the person in silently or returns an error, and never shows a page.
  • max_age: the longest time, in seconds, since the person last signed in. If their session is older, they sign in again.
  • acr_values: the authentication strength you need. See Tokens and claims.
  • organization_hint: for apps that serve several organizations. See Organizations.

A bad request stays on SSO

If a request is malformed, or its redirect URI isn't registered, SSO shows an error page instead of redirecting. That protects your users from open redirects. See Errors.

4. Handle the callback

After sign-in, SSO redirects to your redirect URI with a one-time code and your state:

HTTP
GET https://app.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj-state

Check that state matches what you sent, then exchange the code straight away: codes are single-use and short-lived. If the callback carries error instead of code, see Errors.

5. Exchange the code for tokens

From your server, post the code to the token endpoint. A server-side app authenticates with its client secret, either in the Authorization header (client_secret_basic, shown here) or as client_id and client_secret form fields (client_secret_post).

Shell
curl -X POST https://sso.aldelo.com/oauth2/token \
  -u 'example-app:YOUR_CLIENT_SECRET' \
  -d grant_type=authorization_code \
  -d code=SplxlOBeZQQYbYS6WxSbIA \
  --data-urlencode redirect_uri=https://app.example.com/callback \
  -d code_verifier=dBjftJeZ4CVP-mJ92K1uhbDQpBqQ9cHqLhmlUA8OTkY

A public client sends no secret and no Authorization header. It sends client_id=example-app as a form field instead; PKCE is its proof.

JSON
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9.example.signature",
  "expires_in": 600,
  "id_token": "eyJhbGciOiJSUzI1NiJ9.example.signature",
  "scope": "openid email",
  "token_type": "bearer"
}

expires_in is your app's access-token lifetime: 600 seconds unless your registration sets another value. There is no refresh token. When the access token expires, sign the person in again; if their SSO session is still live, prompt=none does it without a page.

6. Validate the ID token

Before you trust the ID token, check its signature, issuer, audience, expiry and nonce; Tokens and claims lists every check. Then use sub as the person's stable ID and organization_id as the organization they signed in to.

7. Read the person's claims

Call /userinfo with the access token when you need the person's email address, or to confirm that their session is still live:

Shell
curl https://sso.aldelo.com/userinfo \
  -H 'Authorization: Bearer ACCESS_TOKEN'
JSON
{
  "email": "person@example.com",
  "email_verified": true,
  "organization_id": "00000000-0000-0000-0000-000000000000",
  "sub": "00000000-0000-0000-0000-000000000000"
}

Next steps

  • Organizations: which organization a sign-in carries, and how people switch.
  • Sessions and logout: sign people out, and hear when their session ends.
  • Errors: everything your callback and API calls can return.