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

Validation and failure cases

A pushed request can fail in two places. The push itself can be refused, in a direct response to the printer's backend. Or the push succeeds, and the browser's later visit with the reference is refused. The two failures look different, reach different parties, and call for different responses.

Errors from the push

All domains and identifiers in these examples are fictional. Suppose a developer changed the printer's callback path in the code but not in its registration. The push fails:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-cache, no-store

{
  "error": "invalid_request",
  "error_description": "The redirect_uri is not valid for this client"
}

The error uses the same JSON format as a token endpoint error. Its code comes from the token endpoint's list or the authorization endpoint's list, whichever fits. A return address problem is a useful case to notice. In the browser, that mistake would have left you on an error page at the photo service, because the service may not redirect to an address it cannot trust and the specification defines no error code for that case. At the PAR endpoint there is no redirect to worry about, so the service can say what went wrong, using invalid_request by default.

ResponseUsual causeThe printer's next step
400 invalid_requestA malformed request, or a return address not valid for this client.Treat it as a configuration fault. Retrying the same push will fail the same way.
401 invalid_clientClient authentication failed.Check the deployed credential against the registration, as for the token endpoint.
400 invalid_scope or unauthorized_clientThe printer asked for something its registration does not allow.Fix the request or the registration.
413The request is larger than the service accepts.Reduce the request.
429Too many pushes from this client in a period.Wait before trying again.

Some errors never come from this endpoint. Because nobody has been asked to sign in or approve anything yet, errors about signing in or consent are decided later, in the browser. A request sent with any method other than POST gets 405.

Whatever the error, your browser has not gone anywhere. You are still on the printer's page, so the printer can tell you that it could not connect your photo account right now and record a safe diagnostic for its developers. It should not fall back to building an ordinary authorization URL, which would quietly give up the protection it chose PAR for.

Errors at the authorization endpoint

The push succeeded, but the reference can still be refused when your browser presents it. It may have expired because you left the page open, been used already, never have existed, or belong to a different client. The photo service rejects each case. PAR borrows the request_uri parameter and its processing rules from JWT-Secured Authorization Requests, the specification the next group covers, and that specification defines an error code for a reference that cannot be used: invalid_request_uri.

Where that error goes depends on what the service still knows. The return address was part of the pushed request. If the service no longer holds that request, it has no validated return address for this attempt, so it typically shows its own error page instead of redirecting. The printer then receives no callback at all. Its pending transaction expires, and the next time you select Connect it pushes a new request.

Two habits keep this rare. The printer pushes when you select Connect, immediately before redirecting, rather than when it renders a page that might sit open for an hour. And the service chooses a lifetime that allows for a slow phone opening a browser.

Once a valid stored request has been loaded, later failures behave as they always have. If you deny access, the error returns to the printer's callback with state and iss, and the printer validates it before showing a message, as in the Errors and denied access lesson.

Parameters in two places

The printer sends only client_id and request_uri to the authorization endpoint. Suppose someone edits the address in the browser to add more:

https://auth.photos.example/authorize
  ?client_id=photo-printer
  &request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Ademo-pushed-request-7
  &scope=photos.read%20photos.delete

The added scope has no effect. Under the borrowed rules, the service uses only the parameters it stored for the reference. Values added to the URL are ignored, and a stricter service refuses a request that carries them. Either way, an edit in the browser cannot change what the printer pushed. High-assurance profiles go further and require clients to send nothing but client_id and request_uri to the authorization endpoint.

The same rule explains why client_id must still match. It is the one value that appears in both places, and a request where the browser names one client while the reference belongs to another is refused.

Requiring PAR and choosing return addresses

A service that offers PAR but still accepts ordinary authorization URLs has added a safer route without closing the old one. Anyone can still write an ordinary URL naming the printer, with whatever parameters the registration allows. The protections apply only to requests that take the new route.

Closing the old route is a policy setting, and it can be announced in metadata. For the whole service, it appears in the authorization server's metadata. For one client, it can be recorded in that client's registration:

Authorization server metadata (excerpt):
{
  "issuer": "https://auth.photos.example",
  "authorization_endpoint": "https://auth.photos.example/authorize",
  "pushed_authorization_request_endpoint": "https://auth.photos.example/par",
  "require_pushed_authorization_requests": false
}

Client registration for photo-printer (excerpt):
{
  "require_pushed_authorization_requests": true
}

Here the photo service does not require PAR from every client, but it does from the printer. Any authorization request for photo-printer that lacks a request URI obtained from the PAR endpoint is refused with invalid_request. Both settings default to false when omitted.

PAR can also change how return addresses are handled. Exact matching against the registered list remains the normal rule. Because the service authenticates the client before the authorization begins, the specification allows a service to relax that rule for clients with credentials, accepting a return address the client supplies in the push without registering it first. A client could then use a distinct address for each authorization server it works with, chosen at run time. The service decides whether to allow this and can still limit it, for example by requiring every such address to start with https://printer.example/oauth/.

That freedom must never extend to unauthenticated pushes. If anyone could push a request with a return address of their choosing, the photo service would send people and their codes wherever an attacker liked. A public client, which cannot authenticate, keeps to its registered addresses.

PAR protects the request by changing the route it takes. JWT-Secured Authorization Requests protects it a different way, by having the client sign it, and the two can be combined.

Try it in the Lab

PUT IT INTO PRACTICE

Check your understanding

Try these questions before moving on. If an answer isn't right, use the feedback and try again.

0 of 2 answered correctly

Enable JavaScript to answer these questions and save progress in this browser.

QUESTION 1 OF 2The printer's push returns 400 with invalid_request and a description saying the redirect_uri is not valid. What should the printer do?

QUESTION 2 OF 2The photo service supports PAR but still accepts ordinary authorization URLs for the printer. What can an attacker still do?

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

Learn identity