2

The OAuth 2.0 specification states:

The authorization server MUST support the use of the HTTP "GET" method [RFC2616] for the authorization endpoint and MAY support the use of the "POST" method as well.

If the authorization server supports the POST method to the authorization endpoint, does it need to:

  • Accept parameters as with the GET method, using the query string
  • Accept the parameters as the request body, either as application/x-www-form-urlencoded or an other format, such as JSON.

Also, is it expected to respond with a 3xx (we use 303 with GET) redirect or can it also respond with 200 including a Location header?

Our use case:

The authorization server is part of a microservice architecture. This specific authorization server is responsible for obtaining identities from remote sources, and returning an ID token to the client. The upstream servers may implement any other protocol such as SAML or domain-specific protocols (such as iDIN).

Because this authorization server is exposed as an additional server, the resource owner does not retain a session with the AS, so we can not authenticate the user using sessions. As such, we are considering to use either the Authorization header to present the RFC9068 JWT or to present it as a custom parameter in a request body. Using a query parameter is not an option because it exposes the token to third-parties, and our web framework supports end-to-end encryption of the request body.

We considered dropping authentication altogether and simply signing an ID token which is then associated to our user out-of-band (i.e. by the client, which does have a session, and then sends the signed ID token to the service with which the user has a session). This is not an option however.

1
  • What is your question?
    – mentallurg
    May 7, 2022 at 15:47

1 Answer 1

1

The quoted section of the RFC refers to the Authorization Endpoint, which is the endpoint through which the transmittion of user credentials is received by the Authorization Server in a way not specified within the OAuth 2.0 spec:

The way in which the authorization server authenticates the resource owner (e.g., username and password login, session cookies) is beyond the scope of this specification.

Most applications display some form of login page at the Authorization Endpoint (either immediately or after redirections), and it is on that login page where credentials are collected; credentials are not collected via GET at the Authorization Endpoint, because the credentials would otherwise end up in the query string, making them accessible to third party javascript running on the client and potentially visible in logs.

POSTing to the Authorization Endpoint is behaviour that is not defined by the RFC beyond stating that a POST may be accepted, but doesn't have to be. You are free to accept credentials in any manner you see fit, as long as you obey the spec-compliant behaviour, which is that a response_type query parameter is provided, and a fragment is not used.

With regard to accepting credentials when POSTing to the endpoint, then - it's up to you. The RFC does not specify how one must specify credentials when interacting with the Authorization Endpoint.

Also, is it expected to respond with a 3xx (we use 303 with GET) redirect or can it also respond with 200 including a Location header?

You should use a 3xx request. The specification requires that the server redirect the user to the redirection endpoint of the client. HTTP 200 with a Location header indicates "I succeeded, and there is some related resource over there". HTTP 3xx indicates "The resource you are looking for is located at this exact location, and you should go there."

As such, we are considering to use either the Authorization header to present the RFC9068 JWT or to present it as a custom parameter in a request body. Using a query parameter is not an option because it exposes the token to third-parties, and our web framework supports end-to-end encryption of the request body.

I assume that the JWT you are referring to would be presented to the Authorization Endpoint in order to start an authorization flow with the Authorization Server. If this is the case, as mentioned above, the RFC does not make any requirements as to how you should implement this; you're free to implement it as you please.

In terms of concealing this information from a third party, the path, query string, headers and body are all protected from third parties when using TLS (which is a requirement of the specification). The only reason to prefer headers and body over path and querystring is to prevent leakage of the token in logs, or to prevent running into the URL character limit. I would personally present the JWT to the Authorization Server in body: the Authorization header is already used with valid OAuth sessions in the form of Bearer tokens. Using the JSON Body better communicates that this is an implementation-specific parameter.


That all being said, what you are describing sounds a lot like the client credential flow, in that you are providing an Authorization Grant, in the form of a JWT, to the end-user. Although one questions what this JWT contains - Usually, a JWT is the result of an Authorization Grant, and is not typically something the client would be able to issue. So, what is in this JWT you wish to send as a proof of authorization to the Authorization Server?

4
  • Hi Dan, thank you for your elaborate reply, it clarifies a lot for me. Regarding your concluding remark, our setup is as follows: - We have system that manages user registration, accounts, user ids etc ("Ident"), which issues a JWT identifying the end-user. - Another system ("Upstream") is used to obtain claims about the identity from other identity providers. Sometimes these idps implement OAuth 2.0 themselves, but in some cases they have flows similar to the authorization code flow, but not OAuth 2.0, or some end-user intervention is required. The Upstream system functions as a facade May 7, 2022 at 10:34
  • to these systems. The Upstream system itself also implements OAuth 2.0 (and this is the system I referred to in the question). As the Upstream system does not maintain the user session (the Ident system does) we have to provide credentials of our user to it (during the authorization code flow) in order to correctly associate the claims from the upstream idp to our user. May 7, 2022 at 10:36
  • Indeed, the client credentials flow is fit for some idps. The concrete use case that sparked this question was the integration of iDIN with Upstream. IDin is a collaboration between Dutch banks were the end-user can identify itself using its internet banking portal. Because of compliance reasons we can not accept the username/password, and usually iDIN also requires approval using a security token (most commonly the internet banking mobile application). The flow is then as follows: May 7, 2022 at 10:39
  • 1) The end-user authenticates with Ident and obtains a JWT, 2) The JWT is then passed to the Authorization endpoint in an authorization request of Upstream to start the flow with the upstream provider (e.g. the bank), 3) the upstream flow is completed and redirects back to Ident, 4) the claims are then retrieved from the upstream identity provider and associated to the end-user that started the flow, 5) Upstream issues an OpenID ID token, which is then accepted as valid proof-of-identity by other services in our system. May 7, 2022 at 10:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .