OPENID CONNECT · LAB
Drive the prompt values and read each answer
Produce login_required, consent_required and account_selection_required on purpose, use the tenant's account chooser, force a fresh sign-in and a fresh consent, and see why none must stand alone.
ReadyUses your lab tenant
The lesson
Builds on: Connecting a sign-in to an account.
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.
Sign in to start this lab and check your progress. Log in or create an account.
Get login_required from a silent check with no session
Recorded as
oauth.authorizerejected (login_required) forlab-collage.Get consent_required for a scope never approved
Recorded as
oauth.authorizerejected (consent_required) forlab-collageabout[email protected].Get account_selection_required with a hint for Ben
Recorded as
oauth.authorizerejected (account_selection_required) forlab-collageabout[email protected].Sign in as Ben from the chooser
Recorded as
oauth.authorizesucceeded (user_signed_in) forlab-collageabout[email protected].Combine none with another prompt value
Recorded as
oauth.authorizerejected (invalid_request) forlab-collage.
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
In Lab Photos, open OAuth > Clients > lab-collage and add
photos.shareto its allowed scopes. Nobody has approved it forlab-collage, which guarantees a consent question. The Lab Photos preset creates the scope.Make sure Ava and Ben have passwords (set in Key accounts on issuer and subject).
source ~/btl-oidc.sh, setSCOPE="openid profile email", and runbtl-lab callbackbefore each request.In a private window, sign in once through
signinas Ava so the browser holds a tenant session and a remembered consent. Then press Start.
Walkthrough
Ask without interrupting, with a session.
signin prompt=none
The browser lands on the listener with a code and no page in between. Redeem and validate, then compare iat and auth_time:
redeem '<code>'
btl-lab verify "$ID_TOKEN" --issuer "$ISSUER" --audience "$CLIENT_ID" --type id --nonce "$NONCE" && part "$ID_TOKEN" | jq '{iat, auth_time}'
iat is now. auth_time is your earlier sign-in.
Why it matters: a silent answer confirms that the browser still holds a session, not that anyone used a credential now, so your session records the older auth_time.
Ask without interrupting, with no session. In the private window open
$ISSUER/accountand choose Sign out. Runsignin prompt=noneagain. The listener printserror=login_requiredwith yourstateandiss. Check both as you would for a success, then show your own sign-in button.
Why it matters: for a silent check an error is an ordinary answer, not a failure to investigate.
Sign in as Ava normally, then ask silently for something she never approved.
SCOPE="openid photos.share"
signin prompt=none
The listener prints error=consent_required.
Why it matters: the tenant would have needed to show a consent page, and prompt=none forbids every page.
Hint at a different account while Ava is signed in.
SCOPE="openid profile email"
signin prompt=none login_hint=ben%40example.com
The listener prints error=account_selection_required.
Why it matters: the tenant compares the hint only after consent is settled, so a client without consent learns nothing about who is signed in.
Open the chooser.
signin prompt=select_account
The tenant shows Choose an account with a button to continue as [email protected] and one to use another account. Choose another account and sign in as Ben, approving the consent page. Validate the result: sub is Ben's.
Why it matters: the chooser belongs to the provider. The client never learns which other accounts exist, and it still identifies the result by iss and sub.
Ask again for a sign-in.
signin prompt=login
The password form appears although a session exists. Sign in as Ava. The new token's auth_time is now.
Why it matters: prompt=login asks for evidence that the person can still sign in, not only that the browser holds a session.
Ask again for consent, alone and combined.
signin prompt=consent
signin "prompt=login%20consent"
Open each URL. The consent page appears every time, and the second also asks for the password first.
Why it matters: prompt is a space-separated list. Consent can be requested again, but its wording stays the provider's.
Break it
nonecombined with anything else:
signin "prompt=none%20login"
The listener prints error=invalid_request. none must stand alone, and the tenant refuses to guess which one you meant.
A value this provider does not list. Read what it supports, then send
createanyway.
GET$ISSUER/.well-known/openid-configuration
Open in console
GET $ISSUER/.well-known/openid-configurationprompt_values_supported is ["none","login","consent","select_account"]. signin prompt=create returns error=invalid_request, so your sign-up link sends create only to providers that list it.
Note: prompt=create is G62. The tenant already has self-service registration at /register. Once the value is supported and listed, this step will send a new user straight to registration and show that the client still cannot assume an account was created.
The silent loop. Sign out, then run
signin prompt=nonethree times in a row. Audit shows threelogin_requiredrejections from one browser within seconds. Write the rule in your notes: one silent check per visit, then wait for the person to choose to sign in.
Check your work
Press Check my progress. The checks look for the three silent errors in order, Ben's sign-in from the chooser, and the refused none login request.
In Audit, filter on oauth.authorize and lab-collage to see each answer beside its request_started event.
Cleanup
Sign Ben out at
$ISSUER/accountand sign Ava back in.Keep
photos.shareonlab-collage; later labs use it.