Rich OAuth 2.0 Authorization Requests

Torsten Lodderstedt
OAuth 2
Published in
3 min readSep 21, 2019

--

It’s been a while since I blogged about the new challenges arising from open banking and other use cases when it comes to OAuth authorization requests.

Meanwhile, I have been entertaining my ideas with a lot of smart people in the community, combined it with existing proposals, such as the FAPI work on pushed request objects and OAuth.xyz, and teamed up with great co-authors to write up concrete specifications.

And here they are:

  • OAuth 2.0 Rich Authorization Request (RAR): introduces the request parameter „authorization_details“ that will carry an array of JSON objects, each of them containing the authorization data for a certain API or resource.
  • OAuth 2.0 Pushed Authorization Requests (PAR): introduces the „pushed authorization requests“ endpoint. This new endpoint allows clients to push authorization requests via a direct POST request to the authorization server instead of sending it through the browser via redirect. The authorization server provides the client with a distinct URI that the client uses as a reference in the subsequent authorization request.

The mechanisms defined in those specifications provide an effective yet simple and secure way to convey complex, fine-grained authorization data in the authorization process.

You might ask yourself „why two specs?“ and the answer is: to foster modularity and flexibility.

RAR can be used in conjunction with different delivery methods, one of them is PAR (and PAR can be used without RAR as well).

The authorization_details parameter can be added to a traditional authorization request as another URI query parameter. If additional protection is needed, the whole request can be wrapped into a JWT according to the JWT Secured Authorization Request (JAR) specification.

If the JWT is too big, the client can utilize the request_uri mechanism defined in JAR. And that’s where PAR kicks in: it provides an interoperable way for pushing the authorization request to the AS in exchange for a request_uri.

How does it look like?

Let’s take the (somehow canonical) example for a request for payment initiation.

The authorization_details would look like this:

[
{
"type": "payment_initiation",
"actions": ["initiate", "status", "cancel"],
"locations":[
"https://example.com/payments"
],
"instructedAmount":{
"currency":"EUR",
"amount":"123.50"
},
"debtorAccount":{
"iban":"DE40100100103307118608"
},
"creditorName":"Merchant123",
"creditorAccount":{
"iban":"DE02100100109307118603"
},
"remittanceInformationUnstructured":"Ref Number Merchant"
}
]

The client would send it as part of a pushed authorization request to the AS (the JSON object is trimmed and URI encoded).

POST /as/par HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUm...
response_type=code&
client_id=s6BhdRkqt3&
state=af0ifjsldkj&
redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&
code_challenge_method=S256&
code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U&
authorization_details=%5B%7B%22type%22%3A%22payment_initiation%22%2C%22actions%22%3A%5B%22initiate%22%2C%22status%22%2C%22cancel%22%5D%2C%22locations%22%3A%5B%22https%3A%2F%2Fexample.com%2Fpayments%22%5D%2C%22instructedAmount%22%3A%7B%22currency%22%3A%22EUR%22%2C%22amount%22%3A%22123.50%22%7D%2C%22debtorAccount%22%3A%7B%22iban%22%3A%22DE40100100103307118608%22%7D%2C%22creditorName%22%3A%22Merchant123%22%2C%22creditorAccount%22%3A%7B%22iban%22%3A%22DE02100100109307118603%22%7D%2C%22remittanceInformationUnstructured%22%3A%22Ref%20Number%20Merchant%22%7D%5D

The AS would respond with a request_uri …

HTTP/1.1 201 Created
Cache-Control: no-cache, no-store
Content-Type: application/json

{
"request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2",
"expires_in": 90
}

… that the client would use in the subsequent authorization request in the front channel.

GET /authorize?request_uri=
urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2 HTTP/1.1

I think that’s the easiest way to handle rich and security sensitive authorization requests in OAuth 2.0.

I would like to thank all the people that contributed to this initiative in one way or the other, namely Brian Campbell, Dave Tonge, Justin Richer, Nat Sakimura, Filip Skokan, Daniel Fett, Aaron Parecki, Sebastian Ebling, Mike Jones, and Rob Otto.

I would like to ask you for your feedback to this drafts via any channel suitable for you, e.g. comments on this article, the OAuth Mailing List or github (RAR, PAR).

--

--

Torsten Lodderstedt
OAuth 2

Torsten is CTO@yes.com, software architect with strong security interest, identity nerd, contributor to OAuth, OpenID, Open Banking & Electronic Signatures