OAUTH 2.0 · LAB
Break pushed requests, then require PAR for one client
Trigger each push error from the lesson's table, show that URL parameters beside a reference are ignored, require PAR for lab-printer, and try the relaxed return-address rule for authenticated pushes.
PlannedUses your lab tenant
The lesson
Builds on: Using the request URI.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
Planned. The core of this lab waits on platform features that are not built yet. The planned walkthrough shows exactly how it will run; Do today is a real exercise you can do now.
- G11 PAR
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
Use
lab-printer,lab-printer-appand the shell variables from the earlier PAR labs. Startbtl-lab callbackbefore each browser attempt.Planned (G11): in OAuth > Flow policy, keep pushed authorization requests Allowed and leave Require PAR for all clients off.
Planned (G11): on
lab-printer, leave Require PAR and Allow redirect URIs supplied in a push off for now.
Planned walkthrough
Push with a typo in the return address,
redirect_uri=http://127.0.0.1:8765/callbak.
curl -s -u "$CLIENT_ID:$CLIENT_SECRET" "$ISSUER/oauth/par" -d response_type=code -d client_id=$CLIENT_ID \
--data-urlencode redirect_uri=http://127.0.0.1:8765/callbak --data-urlencode "scope=openid photos.read" \
-d state=$STATE -d code_challenge=$CHALLENGE -d code_challenge_method=S256 | jq .
Expect 400 {"error":"invalid_request","error_description":"..."} as JSON.
Why it matters: "Errors from the push". In the browser this mistake ends on the tenant's error page. At the push there is no redirect to protect, so the tenant can say what went wrong.
Work through the rest of the lesson's table, and write down the client's next step for each:
scope=openid photos.delete:400 invalid_scope. Fix the request or the registration.A
statevalue of about 2 MB:413. Reduce the request.Pushes in a short loop until the tenant answers
429withRetry-After: wait before trying again. The limit appears as a usage policy in the tenant's usage view.
Why it matters: each row has a different correct response, and none of them is "retry the same push" or "fall back to an ordinary authorization URL".
Push a valid request, then add a parameter in the address bar beside the reference.
echo "$ISSUER/oauth/authorize?client_id=$CLIENT_ID&request_uri=$(urlenc "$REQUEST_URI")&scope=$(urlenc 'openid photos.read photos.delete')"
Open it and sign in as Ava. The consent screen shows only photos.read. If the tenant chooses strict mode, the request is refused instead.
Why it matters: "Parameters in two places". Only the stored parameters count, so an edit in the browser cannot change what the client pushed.
Turn on Require PAR for
lab-printer. Discovery still saysrequire_pushed_authorization_requests: falsefor the tenant, while the client's record saystrue. Open an ordinary authorization URL forlab-printer: the listener receiveserror=invalid_request.
Why it matters: offering PAR without closing the ordinary route protects only the requests that choose the new route.
Turn on Allow redirect URIs supplied in a push for
lab-printer, with the allowed prefixhttp://127.0.0.1:8765/callback/. Push withredirect_uri=http://127.0.0.1:8765/callback/review-482, which is not registered. Expect201, and after approval the callback arrives at the new path.
Why it matters: because the tenant authenticated the client first, it can safely relax exact matching inside a boundary the tenant chose.
Restore: turn Allow redirect URIs supplied in a push off on lab-printer and save.
Try the same unregistered return address in a push from
lab-printer-app, which has no credential. Expect400 invalid_request. The setting is not offered for public clients.
Why it matters: the relaxation must never extend to unauthenticated pushes, or anyone could send people and their codes to an address of their choosing.
Do today
Compare where today's return-address mistakes surface. Open an authorization URL for
lab-printerwithredirect_uri=http://127.0.0.1:8765/other: the tenant shows its own error page and the listener receives nothing.Make the same mistake at the token endpoint instead. Get a code with the correct address, then redeem it with the wrong one.
curl -s -u "$CLIENT_ID:$CLIENT_SECRET" "$ISSUER/oauth/token" -d grant_type=authorization_code \
-d code=<code> --data-urlencode redirect_uri=http://127.0.0.1:8765/other -d code_verifier=$VERIFIER | jq .
The answer is 400 invalid_grant, and Audit shows oauth.token rejected redirect_uri_mismatch. Note how much later each mistake surfaces than it would at a push, and that the first one never reaches the client at all.
Confirm the method rule from the lesson's table.
GET$ISSUER/oauth/par
Open in console
GET $ISSUER/oauth/parThe answer is 405 with Allow: POST.
Look for the settings the lesson describes. Discovery has no
require_pushed_authorization_requests, and thelab-printerform has no Require PAR option. Note that with no PAR at all, every request for this client takes the ordinary route.
Break it
These run once G11 exists.
Expired reference: push, wait past
expires_in, then open the address. The tenant shows its error page withinvalid_request_uri, and no callback arrives. The client's pending attempt simply times out; the fix is to push immediately before redirecting.With Require PAR on, try to set the redirect prefix to
https://, which would allow every address. The tenant refuses the setting, because a prefix must include a host.
Check your work
Today, Audit shows oauth.token rejected redirect_uri_mismatch, and Logs show oauth.par rejected method_not_allowed. Once G11 exists, Audit also shows oauth.par rejections for the return address, scope and rate limit, an oauth.authorize refusal because PAR is required, and tenant.oauth.clients.update for the Require PAR and redirect prefix changes.
Cleanup
Turn Require PAR off on
lab-printer, so later labs can use ordinary requests.Confirm Allow redirect URIs supplied in a push is off.
Missing infrastructure
G11: beyond the PAR endpoint, this lab needs a per-client
require_pushed_authorization_requestssetting, a tenant-wide requirement, a per-client redirect prefix for authenticated pushes (never for public clients), a request size limit that answers413, and a push rate limit registered as a visible tenant usage policy. Once these exist, the Planned walkthrough runs as written.