Table of Contents

Authorization Code Flow

This is a walkthrough of the authorization code flow (or grant in OAuth2 language).
The intention of this guide is to give you a practical, easy to follow reference for how to use this flow for authentication and to retrieve an Access Token (and/or a Refresh Token).

There are three steps to the authorization code flow:

  1. Initiation
  2. Code Exchange
  3. Getting a new Token

1. Initiation

To initiate the authorization flow, you need to begin by putting together the request URL.
This has the following Query Parameters:

  • client_id
    Required: Yes
    Valid Values: the client id that you have been provided with
  • response_type
    Required: Yes
    Valid Values: code
  • scope
    Required: Yes
    Valid Values: openid, profile, email, offline_access
  • redirect_uri
    Required: Yes
    Valid Values: Any valid redirect URI that has been registered with the client
  • state
    Required: No
    Valid Values: any custom value, is passed through and returned
  • code_challenge
    Required: No
    Valid Values: a valid challenge hashed using SHA256, or plain text if the code_challenge_method is set to plain'
    Notes: This should be provided if you are using the PKCE (Proof Key Code Exchange) variant of the authorization flow. We do recommend this, as it is more secure.
  • code_challenge_method
    Required: Conditional
    Valid Values: S256, plain
    Notes: This is only required if code_challenge is provided
Note

Users can create Code Challenge by performing SHA256 hash on the code verifier and then by Base64url encoding the hash.
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

Example Authorization Request

curl https://signin.test.purefarming.com/auth/realms/moa/protocol/openid-connect/auth?
     client_id=myclient&
     response_type=code&
     scope=openid%20profile&
     redirect_uri=http://localhost/callback&
     state=abc123&
     code_challenge=xyz098&
     code_challenge_method=plain

In the above example we've set up an authentication/authorization request for use on a local machine. This request is targeting http://localhost/callback and provides a state value of abc123, this value will be passed through
in plain text throughout the authorization flow.

Once you have put together the authorization URL, the end user's browser must be redirected to it. The user will be asked to login and validate their credentials.
If necessary (depending on client configuration) the user may be asked to confirm the access being requested.
After they have logged in and granted any necessary permissions, the user will be redirected to the redirect_uri that you provided.

2. Code Exchange

Once the users browser has been redirected to the redirect_uri that you have provided, the response will include the code and state.
As part of the URI that the browser is redirected to, the URI will include the code and state parameters, take a look at the example below:

http://localhost/callback?code=xyz098&state=abc123

You will then need to parse the code out as this is required as part of the Code Exchange step.
The state may, or may not be useful to you but can be used to identify a particular instance of the flow if you need to do so.

To complete the code exchange you need to make a POST request to the token endpoint.

The POST request can either be a form encoded request, or a JSON request, the example below is for a form encoded request.

The following parameters need to be provided for the code exchange request:

  • grant_type
    Required: Yes
    Valid Values: authorization_code
  • client_id
    Required: Yes
    Valid Values: the client_id that you have been provided with
  • code
    Required: Yes
    Valid Values: the code that was returned in the response from the authorization server
  • redirect_uri
    Required: Yes
    Valid Values: the same redirect URI that you provided in the authorization request
  • code_verifier
    Required: Conditional
    Valid Values: the plain text that you used to create the code_challenge, if you set code_challenge_method to S256 then this is the clear text, otherwise it is the same value. This is only required if you used the PKCE variation of the flow

Example Request

curl -H Content-Type: application/x-www-form-urlencoded \
     -d grant_type=authorization_code&client_id=<<your client id>>&code=<<returned code>>&redirect_uri=http://localhost/callback&code_verifier=xyz098 \
     https://signin.test.purefarming.com/auth/realms/moa/protocol/openid-connect/token

Example Response

{
    "access_token": "...",
    "id_token": "...",
    "refresh_token": "...",
    "expires_in": 3600
}

The response returned above includes three different tokens, see tokens for more information.

The response also includes the expires_in value which is the number of seconds until the returned access_token expires.

3. Getting a new Token

In order to retrieve a new token using a refresh_token, another request must be made to the "token" endpoint.

This can be done as either a URL Encoded POST or a JSON POST.

curl -H Content-Type: application/x-www-form-urlencoded \
     -d grant_type=refresh_token&client_id=<<your client id>>&refresh_token=<<stored refresh_token>> \
     https://signin.test.purefarming.com/auth/realms/moa/protocol/openid-connect/token

The response from this is the same as the initial response at the code exchange step. See example response for more information.