Definitive Guide

Authorization response

  1. Response Parameters
  2. Response Format
  3. Error Response
  4. When Redirect URI Is Unavailable

1. Response Parameters

According to RFC 6749, on success, the authorization endpoint issues either an authorization code or an access token.

OpenID Connect has added another object which may be returned from the authorization endpoint (and/or the token endpoint). It is an ID token. OpenID Connect Core 1.0 says "The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure."  (an excerpt from "OpenID Connect Core 1.0, 2. ID Token").

Short summaries of the objects are as follows.

Objects Returned From The Authorization Endpoint
Authorization Code Access Token ID Token

An opaque string or number which is a kind of short-lived ticket to be exchanged with an access token at the token endpoint.

An opaque string or number which denotes who (end-user) has granted what permissions (scopes) to which client application.

(An access token issued using Client Credentials Flow has no information about who.)

A JWT which contains pieces of information about the end-user.

Before OpenID Connect, it was a simple world where the authorization endpoint returned either an authorization code or an access token. Not both. However, after OpenID Connect, the authorization endpoint returns at maximum all the three objects depending on the value of the response_type request parameter. The following table illustrates the relationship between response_type and returned objects.

The Relationship Between response_type and Returned Objects
response_type Returned Objects
Authorization Code Access Token ID Token
none
code
token
id_token
code token
code id_token
id_token token
code id_token token

In a response from the authorization endpoint, an authorization code, an access token and an ID token are embedded using code key, access_token key and id_token key, respectively. For example, code=SplxlOBe in a response means that the value of the authorization code is SplxlOBe.

Response parameters that may be returned from the authorization endpoint are as follows.

Response Parameters From The Authorization Endpoint
No. Name Description
1 code

An authorization code issued to the client application. This is contained in a successful response when response_type request parameter of the authorization request contained code.

2 access_token

An access token issued to the client application. This is contained in a successful response when response_type request parameter of the authorization request contained token.

3 id_token

An ID token issued to the client application. This is contained in a successful response when response_type request parameter of the authorization request contained id_token.

4 state

When an authorization request contains state request parameter, the authorization endpoint includes the parameter in the authorization response without changing the value.

5 error

An error code. This is contained in a response when an error occurred.

6 error_description

The short description of the error which happened. This may be contained in a response when an error occurred.

7 error_uri

The URI where the detailed description of the error can be found. This may be contained in a response when an error occurred.

8 token_type

The token type of the access token. This is contained in a successful response when response_type request parameter of the authorization request contained token.

9 expires_in

The lifetime in seconds of the access token. This may be contained in a successful response when response_type request parameter of the authorization request contained token.

10 scope

A space-delimited scope list of the access token. This may be contained in a successful response when response_type request parameter of the authorization request contained token.

2. Response Format

According to RFC 6749, in both Authorization Code Flow and Implicit Flow, the HTTP status of a successful response from the authorization endpoint is "302 Found", which triggers the user agent (= the web browser the end-user is using) to be redirected to another location from the authorization endpoint. In OAuth 2.0, the destination location is called redirect URI.

Response parameters are returned to the client application as a part of the redirect URI. For example, if (1) the flow is Authorization Code Flow, (2) the redirect URI is https://client.example.org/callback, and (3) the value of the authorization code is ap8uacb2, the response from the authorization endpoint to the client application will look like the following.

HTTP/1.1 302 Found
Location: https://client.example.org/callback?code=ap8uacb2
Cache-Control: no-store
Pragma: no-cache

Another example. If the flow is Implicit Flow and the value of the access token is pqb8u3t, the response will look like the following (with extra line breaks for display purposes only).

HTTP/1.1 302 Found
Location: https://client.example.org/callback#access_token=pqb8u3t
                                             &token_type=Bearer
                                             &expires_in=3600
Cache-Control: no-store
Pragma: no-cache

You might have noticed that the response parameters in Authorization Code Flow are embedded in the query component (= the part after '?') but those in Implicit Flow are embedded in the fragment component (= the part after '#'). This difference is a requirement by RFC 6749. In either case, "302 Found" is used. The following table summarizes the relationship between response_type and response parameters' location.

Relationship Between response_type And Response Parameter's Location
response_type HTTP status Response Parameters' Location
code 302 Found Embedded in the query component of the redirect URI in the Location header.
token 302 Found Embedded in the fragment component of the redirect URI in the Location header.

However, OpenID Connect, to be exact, OAuth 2.0 Form Post Response Mode, has added some complexities here. It has introduced a mechanism to control the response format and added "200 OK" with an HTML as a new response format. This format is used when an authorization request comes along with response_mode=form_post. The following is an excerpt from the specification (with extra line breaks for display purposes only).

In the HTML above, the redirect URI is set as the value of action attribute of the form tag and response parameters as hidden parameters. You can find two response parameters, namely, state and id_token. (In this example, neither code nor access_token is embedded.)

After the HTML above is loaded by the user agent, the JavaScript written in the onload attribute of the body tag is executed. As a result, redirection to the redirect URI is performed.

The table below illustrates the relationship between combinations of response_type & response_mode and the HTTP status & response parameters' location. Note that the query component is not usable when an access token and/or an ID token are contained in the response.

Relationship Between response_type/response_mode Combinations And HTTP Status/Response Parameters' Location
response_type response_mode
(default) query fragment form_post
302 Found 200 OK
none Query component Query component Fragment component Hidden parameters
code
token Fragment component NOT ALLOWED Fragment component Hidden parameters
id_token
code token
code id_token
id_token token
code id_token token

3. Error Response

When an error occurs while a service is processing an authorization request, the service returns an error response to the client application. If the redirect URI to which the error should be reported had been determined before the error occurred, the redirect URI can be used.

When a redirect URI can be used, the error response parameter is always embedded. In addition, the error_description response parameter and the error_uri response parameter may be optionally embedded. For example, an error response looks like the following. (extra line breaks for display purposes only)

HTTP/1.1 302 Found
Location: https://client.example.org/callback?error=access_denied
  &error_description=The%20end-user%20denied%20the%20authorization%20request.
Cache-Control: no-store
Pragma: no-cache

RFC 6749 defines values of error response parameter which may be returned from the authorization endpoint in 4.1.2.1. Error Response (for Authorization Code Flow) and in 4.2.2.1. Error Response (for Implicit Flow). OpenID Connect Core 1.0 added values in 3.1.2.6. Authentication Error Response. The table below aggregates the error codes in alphabetical order.

Values Of error From The Authorization Endpoint
No. Value Specifications
RFC 6749 OpenID Connect
1 access_denied
2 account_selection_required
3 consent_required
4 interaction_required
5 invalid_request
6 invalid_request_object
7 invalid_request_uri
8 invalid_scope
9 login_required
10 registration_not_supported
11 request_not_supported
12 request_uri_not_supported
13 server_error
14 temporarily_unavailable
15 unauthorized_client
16 unsupported_response_type

4. When Redirect URI is Unavailable

Errors may occur before the redirect URI is determined. For example, if the specified client ID (client_id) is invalid, it is impossible to check whether the specified redirect URI (redirect_uri) has been registered or not, so the error cannot be reported to the redirect URI.

RFC 6749, 3.1.2.4. Invalid Endpoint says:

If an authorization request fails validation due to a missing, invalid, or mismatching redirection URI, the authorization server SHOULD inform the resource owner of the error and MUST NOT automatically redirect the user-agent to the invalid redirection URI.


but the means about how to inform the resource owner (= end-user) of the error is not described anywhere. Therefore, the authorization endpoint has to decide its way. The following are some candidates of response formats.

HTTP Status Content-Type Comment
400 Bad Request text/html

The error is described in HTML format and shown in the user agent. This is friendly to end-users and testers.

400 Bad Request application/json

The error is described in JSON format in the same way as the token endpoint does (RFC 6749, 5.2. Error Response). This is friendly to developers of client applications.

Considering that OpenID Connect has added a use case (prompt=none) where no user interaction is performed, application/json might be better.