Pushed Authorization Requests (PAR)

Introduction


Despite in Draft state (or a specification under development), the Pushed Authorization Requests is one the most impactful security enhancements to the OAuth2 framework.

The security enhancement allows clients to "push" an authorization request, in advance of sending conventional one, to an authorization server. The PAR specification defines an endpoint for provisioning of the authorization request. The endpoint send back an identifier (request_uri) so that the client can include it in the proper authorization request. 

The segregation of the provisioning of the authorization from the authorization request itself creates one more option to enhance the security, for instance: SPA apps can rely on server side to create the authorization request without disclosing any detail of the authorization request to the browser, or mobile apps can create the authorization request before forwarding it to browser.

​​This article describes an overview of PAR support in Authlete, and instructions to enable it.




PAR requests


To implement the support for pushed authorization requests, you have to implement the PAR endpoint in the authorization server (or OP on OIDC parlance), and configure Authlete to enable the PAR support.

The pushed authorization endpoint of the authorization server can rely on the /pushed_auth_req API of Authlete. The /pushed_auth_req API has the same design principle as the other endpoints: your authorization server can forward the pushed authorization request from a client (via a user agent)  directly to Authlete, and we have your back.

Authorization code flow using Pushed Authorization Requests


The /pushed_auth_req API expects the same payload of /auth/authorization API, plus the client authentication. The /pushed_auth_req API will make a response content that includes a request_uri so that the client can use it  on making an authorization request.

Sample request and response


The content of the pushed request can be the same as ones in a usual request to an authorization endpoint. Except that the client itself sends the authorization request in a POST request using application/x-www-form-urlencoded media type.

The sample request below, shows an interaction between an authorization server and Authlete’s /pushed_auth_req API. The content of the pushed authorization request, which initiates an authorization code flow with a PKCE in this example, should be provisioned by a client. 

The response from Authlete is the action "CREATED" and a requestUri, meaning that the authorization request was provisioned with an identifier as the requestUri value. Authlete also creates responseContent, whose value is intended to be used as a pushed authorization response from the authorization server to the client.

curl --request POST 'https://api.authlete.com/api/pushed_auth_req' \
--header 'Authorization: Basic ************' \
--header 'Content-Type: application/json' \
--data '{ 
    "parameters": "response_type=code&
                   client_id=3280859750204&
                   redirect_uri=https%3A%2F%2Fmobile.example.com%2Fcb&
                   code_challenge=W78hCS0q72DfIHa...kgZkEJuAFaT4&
                   code_challenge_method=S256",
    "clientId": "3280859750204"}'
{
    "type": "pushedAuthReqResponse",
    "resultCode": "A245001",
    "resultMessage": "[A245001] Successfully registered a request object for client (3280859750204), URI is urn:ietf:params:oauth:request_uri:UymBrux4ZEMrBRKx9UyKyIm98zpX1cHmAPGAGNofmm4.",
    "action": "CREATED",
    "requestUri": "urn:ietf:params:oauth:request_uri:UymBrux4ZEMrBRKx9UyKyIm98zpX1cHmAPGAGNofmm4",
    "responseContent": "{\"expires_in\":600,\"request_uri\":\"urn:ietf:params:oauth:request_uri:UymBrux4ZEMrBRKx9UyKyIm98zpX1cHmAPGAGNofmm4\"}"
}

Using the request_uri returned from pushed_auth_req endpoint, the client starts the authorization on the authorization server via an user agent. On receiving the request, the authorization server makes a request to Authlete’s /auth/authorization API as follows.

curl --request POST 'https://api.authlete.com/api/auth/authorization' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic *************' \
--data '{ 
    "parameters": 
       "client_id=3280859750204&
        request_uri=urn:ietf:params:oauth:request_uri:UymBrux4ZEMrBRKx9UyKyIm98zpX1cHmAPGAGNofmm4" 
  }'

The response of Authlete is the same as the regular authorization request. A ticket will be created - check the details under the note describing Authlete ticket.




Authentication of clients


For pushing authorization requests, the client needs to authenticate itself on the authorization server with its client type (public / confidential) and the authentication method of the client. The mechanism is the same as the /auth/token API, which is described in the following article.


Under the Developer Console, you can find the authentication method for the client under "Authorization" tab of the client.

Client authentication method of the client on token and par endpoint


For the authentication method CLIENT_SECRET_BASIC, the client will be authenticated on the pushed authorization request using basic HTTP authentication. The authorization server will make a request to Authlete’s /pushed_auth_req API with the credentials submitted from the client, by using the "clientId" and "clientSecret" attributes (check snipped below).

curl --location --request POST 'https://api.authlete.com/api/pushed_auth_req' \
--header 'Authorization: Basic MjQzNDE1ND*********LWtv' \
--header 'Content-Type: application/json' \
--data-raw '{ "parameters": "response_type=code%20id_token&client_id=3280859750204&redirect_uri=https%3A%2F%2Fserver.example.com%2Fcb&state=SOME_VALUE_ABLE_TO_PREVENT_CSRF&scope=openid&nonce=SOME_VALUE_ABLE_TO_PREVENT_REPLAY_ATTACK&code_challenge=GyeodZxSpq0iyjNbEQE6N96MxomMXYpYUkfuEpvQ3Js&code_challenge_method=S256",
  "clientId": "3280859750204",
  "clientSecret" : "qfd0ScLHhD**************YDg"}'

If the client is configured for a client certificate based authentication method, the request will be similar to the request below.


curl --location --request POST 'https://api.authlete.com/api/pushed_auth_req' \
--header 'Authorization: Basic MjQzNDE1ND*********LWtv' \
--header 'Content-Type: application/json' \
--data-raw '{ 
  "parameters":"response_type=code&client_id=....",
  "clientId":3282602314604,
  "clientCertificate":"\n-----BEGIN CERTIFICATE-----\nMIICnDCCAYSgAwIBAgIGAXqsMta0MA0GCSqGSIb3DQEBCwUAMA8xDTALBgNVBAMM\nBGtleTEwHhcNMjEwNzE1MjIwNDEwWhcNMjIwNTExMjIwNDEwWjAPMQ0wCwYDVQQD\nDARrZXkxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh517rALrL+I9\npvOpCVr9wuJ/TE3l3CndvE9oRrU2BpBYSn0LVnIT6anKgrYSJNP/YOkgHqUQQIoq\n0j7Uv7fiYL02OuAuVouOP3pxC1QiRGNInZkmYVJ0EsNz8Gft3JW7A9pUHc/Sx0P1\nTbN1hL9J5auasCNjUhd3GCB7bEJeIlez066qkUeZR/Jtpqdh9TVJrnBjEiihrcwL\nlixo4G5Y2Tg9vpjOCKgoL1tni6wbxY64BzksF2y10OEfvcwacmLBsMxHhN3l0qU2\nnbKbYKb2R0xRq8DU5woG0Rkbi5z6FRF4DLzpjig6vk6ENjwenHFYt8XMhulmSdnX\nGvDe2/BWYQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQABRsoLK5hn5DesBpnDCBfq\nZnyMiWyUbh8qmIhO5Ta6Hq/AeUSM16gqJqBsLQm6UllfsW30Qn9EwkCMG1Fb4g8t\n5TVigtvtVcTkn3H2Ib6EhtsB5Evs1U273W5Z/y7QUDrS2TahraKNKK2k81UbHhZf\nY1qyDMTK1+a+EAcuUaFOPsOzZo3Yxa2GDXQ8ZjHwk4E7tIri953P66gGHC3GNTy92hrXw8KgoIXJXKyZ5WeyziTIfAypnlI6EzUU\n-----END CERTIFICATE-----"}'

In case of TLS_CLIENT_AUTH using PKI authentication - where Authlete can validate the client certificate chain against a list of root CAs - the authentication will be similar to the request below 

curl --location --request POST 'https://api.authlete.com/api/pushed_auth_req' \
--header 'Authorization: Basic MjQzNDE1ND*********LWtv' \
--header 'Content-Type: application/json' \
--data '{
  "parameters":"response_type=code&client_id=3289644915401&...",
  "clientId":3289644915401,
  "clientCertificate":"\n-----BEGIN CERTIFICATE-----\nMIIDmzCCAoOgAwIBAgI.....ftMPIhU1ocI0Uh9ObkPq5atK0lx\n39OTMXLj1kHxlf3RnoRo\n-----END CERTIFICATE-----",
  "clientCertificatePath":["\n-----BEGIN CERTIFICATE-----\nMIIE3TCCAsWgAwI.....9HEtxsOeIDWmILz453xtSBdorV7rN7QcEK6Hd62czruZtk/ItPjQMnB1moBT3d\n5g==\n-----END CERTIFICATE-----",
                           "\n-----BEGIN CERTIFICATE-----\nMIIFuDCCA6CgAwI.....FRVZqvemtV0gZM0C3tkDBQzGsb/KW\nnFWbOABBQequSMJN0MjWd+fkiDZAJq/X0Gw==\n-----END CERTIFICATE-----"]}'


PAR configuration on Authlete


Under the Service Owner Console, the administrator can configure an Authlete service to work as a backend of the PAR endpoint on the authorization server, for how long a pushed authorization request will be valid, and if the usage of PAR is mandatory for every client.

Pushed Authorization Request config on service level

PAR requests are single usage and have a duration to restrict the valid PAR requests flying around.

You can configure PAR to be mandatory for a specific client, even if the Authlete service is configured to not require it. Under "Authorization" tab of the client in the Developer Console, you find the parameter below:
How did we do with this article?