Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

BTL Admin

OPENID CONNECT · LAB

Name the provider, the relying party and the issuer in your own tenant

Map the OpenID Connect roles onto Lab Photos and lab-collage, find one issuer in four places, and change how the provider authenticates Ava without the relying party changing anything.

ReadyUses your lab tenant

The lesson

Builds on: From delegated access to sign-in.

New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.

Your progress

Press Start before you begin. Only events your tenant records after that count, in the order below. Checking reads your tenant's Audit, so you need Audit read access in it.

  1. Sign Ava in to lab-collage with a password

    Recorded as oauth.authorize succeeded (code_issued) for lab-collage about [email protected].

  2. Ava adds an authenticator app

    Recorded as account.security succeeded (method_enrolled) about [email protected].

  3. The provider asks Ava for her code

    Recorded as account.second_step succeeded (second_step_completed) about [email protected].

  4. lab-collage receives tokens after the stronger sign-in

    Recorded as oauth.token succeeded for lab-collage about [email protected].

Request console

Requests in this lab can be sent from this page to your tenant: open one and choose Send. Fill in the values below first. They stay in this page's memory and are gone when you leave; secrets are never stored or sent anywhere except the request you send.

Setup

  1. You need lab-collage, Ava and the shell variables from the first lab in this track, plus an authenticator app (or oathtool) for a time-based code.

  2. If Ava already has an authenticator app from an earlier lab, remove it as Ava at $ISSUER/account/security, so this lab starts with password-only sign-in.

  3. Keep btl-lab callback running in a second terminal.

  4. Press Start.

Walkthrough

  1. Map the roles. Fill in the lesson's role table with real names from your tenant:

OpenID Connect roleIn your labOAuth role it builds on
End-UserAva ArcherResource owner
Relying Partylab-collageClient
OpenID ProviderLab Photos at $ISSUERAuthorization server
UserInfo endpoint$ISSUER/oidc/userinfoProtected resource

Why it matters: these are the names you use for the rest of the track. The provider is the same authorization server you used in the OAuth labs, with a second job.

  1. Sign Ava in through lab-collage with scope=openid, as in the first lab: eval "$(btl-lab pkce)"; eval "$(btl-lab state)", open the authorization URL, sign in with Ava's password, and exchange the code with -u "$CLIENT_ID:$CLIENT_SECRET". Keep ID_TOKEN.

  1. One issuer, four places. Write down the iss value the listener printed from the callback. Then read the provider's own statement of its issuer:

GET$ISSUER/.well-known/openid-configuration Open in console
GET $ISSUER/.well-known/openid-configuration HTTP/1.1
Accept: application/json

Compare all four values byte for byte:

echo "$ISSUER"
curl -s "$ISSUER/.well-known/openid-configuration" | jq -r .issuer
btl-lab decode "$ID_TOKEN" | grep '"iss"'

Why it matters: everything the relying party trusts about the provider hangs from this exact string. Your configuration, the discovery document, the callback and the token must agree character for character.

  1. Registration carries over. Open lab-collage in OAuth > Clients. Its client ID, redirect URIs, confidential type and secret are ordinary OAuth settings, and nothing marks it as a "relying party".

Why it matters: a relying party is still an OAuth client. OpenID Connect adds responsibilities to the client (checking the ID token, finding the account, running a session), not a new kind of registration.

  1. Record how the provider authenticated Ava: btl-lab decode "$ID_TOKEN" shows amr: ["pwd"] and an auth_time.

  1. The provider changes how it authenticates. In Authentication, set the authenticator app (TOTP) method to optional if it is off. As Ava, open $ISSUER/account/security and add an authenticator app. By default the tenant asks every user who has a second method for it at sign-in.

  1. Start a new lab-collage sign-in with &prompt=login appended to the authorization URL, so the existing session is not reused. Sign in with Ava's password, enter the code from the app, exchange the code and decode the new ID token. amr now includes otp and mfa, and auth_time is new.

Why it matters: the relying party sent the same kind of request both times. The provider alone decided to authenticate Ava more strongly, and reported how in the token.

  1. The relying party decides what happens next. Write down one action the collage app might protect, for example "delete a shared collage". Nothing in the ID token grants or denies it.

Why it matters: the provider says who signed in and how. Whether that person may delete the collage stays the application's own authorization decision.

Break it

  1. Configure the relying party with a near-miss issuer and validate the token you just received:

btl-lab verify "$ID_TOKEN" --issuer "$ISSUER/" --audience "$CLIENT_ID" --type id --nonce "$NONCE"
btl-lab verify "$ID_TOKEN" --issuer "$ISSUER" --audience "$CLIENT_ID" --type id --nonce "$NONCE"

The first run stops at the issuer check because of one trailing slash. The second ends in ACCEPT. An issuer is compared exactly, never normalized.

  1. Sign in as Ben with &prompt=login in a fresh private window. He has no second method, so the provider asks only for his password and his token says amr: ["pwd"]. Same relying party, same request, different authentication, decided by the provider for each person.

Check your work

Press Check my progress. The checks look for, in order:

  • oauth.authorize succeeded with code_issued for lab-collage and Ava.

  • account.security succeeded with method_enrolled for Ava.

  • account.second_step succeeded with second_step_completed for Ava.

  • oauth.token succeeded for lab-collage and Ava after the second step.

In Audit you also find tenant.authentication.update if you turned TOTP on in step 6, and oauth.authorize with user_signed_in for each password sign-in.

Cleanup

  1. As Ava, remove the authenticator app at $ISSUER/account/security. Later labs in this track sign Ava in with her password only.

  2. If TOTP was off before step 6, set it back to off in Authentication.

Back to all labs

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow All", you consent to optional analytics. Cookie Policy

The Lab