Pushed Authorization Request lifetime in OpenID Connect

604 views Asked by At

As we can see here: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-par#section-2.2 pushed authorization request lifetime should be between 5 and 600 seconds.

So assume that it's 60 seconds. Then client redirects user to authorization endpoint and... user is not logged in. So authorization endpoint redirect the user to endpoint with login page with request_uri as query param. The user logs in, login page redirect user to authorization endpoint with request_uri from query param. Probably, if lifetime was about 10s the request_uri is expired now (and what's more it's used more than once). So how can we handle the flow when user is not authenticated while he is redirected to authorization endpoint and we use PAR?

I know that can be 600 seconds also, but the recommendations say that this lifetime should be as short as possible. Therefore, it seems to me that I misunderstand how PAR works. I don't think even 10 minutes is enough because what if user currently doesn't have account at the identity provider or there is MFA used?

Please tell me, how PAR really works.

1

There are 1 answers

10
Gary Archer On

Consider a browser based app implementing this flow:

STEP 1

The browser wants to begin a login and calls its backend. The backend sends a standard Open ID Connect request like this to the authorization server:

POST https://login.example.com/oauth/authorize/par

Authorization: Basic czZCaFo3RmpmcDBa:QnIxS3REUmJuZbUl3

client_id=myclient&
redirect_uri=http%3A%2F%2Fwww.example.com%2F&
scope=openid%20profile&
response_type=code&
response_mode=jwt&
code_challenge=WQ4Y4CQpO8W6VtELopzYHdNg&
code_challenge_method=S256&
state=NFBljlVuB1GDjgGARmqDcxtHhV8

The authorization server saves the OIDC request details. Note also that the authorization header includes the client secret, which is one of the key features of PAR - the client authenticates before the redirect to the authorization server. So a malicious app cannot redirect a user with your client ID, since they do not know the secret.

STEP 2

The browser then uses the request URI. The short time you mention is only for this redirect and does not impact user login time:

https://login.example.com/oauth/authorize?
client_id=myclient&
request_uri=urn:ietf:params:oauth:request_uri:7d353fc8-9b94-488f-8c61-cf7cc1dfef9e"

STEP 3

The user logs in, and in some cases that might take a minute or so, as you say. Then a response is returned to the browser:

https://www.example.com/callback?response=eyJra...

In this example I am receiving the response as a JWT, using a related standard called JARM that can be used in conjunction with PAR. The JWT looks like this and could contain an error response in some cases:

{
  "exp": 1629112321,
  "iss": "https://login.example.com",
  "aud": "myclient",
  "iat": 1629112301,
  "purpose": "authz_response",
  "code": "abcdef",
  "state": "12345abcdef"
}

If you don't use JARM you will instead receive code, state and error fields in the browser URL. The flow finishes with the usual authorization code grant POST, to swap the code for tokens.

SUMMARY

All of the above is designed to prevent man in the browser attacks. Eg a malicious party cannot alter any fields in flight. Extra security is therefore added to the standard code flow.