Authorization Code Grant with PKCE
  • 19 Nov 2023
  • 3 Minutes to read
  • Dark
    Light

Authorization Code Grant with PKCE

  • Dark
    Light

Article summary

Using Agile.Now's identity platform, which supports OAuth 2.0 and OpenID Connect (OIDC), you can implement a secure sign-in and API access system for your mobile and desktop apps. The Authorization Code Flow with PKCE (Proof Key for Code Exchange) is particularly suited for apps installed on a device, providing enhanced security for accessing protected resources like web APIs.

Requesting an Authorization Code with PKCE

The flow begins with the client directing the user to Agile.Now's /oAuth/Authorize endpoint. In addition to the standard parameters, PKCE requires generating a code verifier and a code challenge.

PKCE Enhancements

  • Code Verifier: A high-entropy cryptographic random string created by the client.
  • Code Challenge: A transformation of the code verifier, typically using SHA256 hash and then base64-url-encoding it.

Authorization Request Example

// Line breaks for legibility only

https://login.agilenow.io/oauth/authorize?
response_mode=query
&response_type=code
&redirect_uri=https%3A%2F%2Facme.com%2Fcallback%2F
&client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=openid%20name
&state=1234567890
&code_challenge=YourCodeChallenge
&code_challenge_method=S256

Parameters for User Authorization (including PKCE)

ParameterRequired/OptionalDescription
code_challengeRequired (PKCE)The PKCE code challenge.
code_challenge_methodRequired (PKCE)The method used to create the challenge.

In the OAuth 2.0 Authorization Code Flow with PKCE (Proof Key for Code Exchange), the code_challenge_method parameter specifies the method used to transform the code verifier into the code challenge. There are two supported methods for generating the code challenge:

  1. Plain

    • Description: In this method, the code challenge is the same as the code verifier.
    • Usage: This method is typically used in environments where the client is unable to perform cryptographic operations, such as basic browser environments or certain constrained devices.
    • Example: If the code verifier is xyz123, the code challenge will also be xyz123.
  2. S256

    • Description: This is the recommended and more secure method. The code challenge is derived by hashing the code verifier with the SHA-256 cryptographic hash function, and then URL-safe base64-encoding the resultant value.
    • Usage: It should be used in environments where the client can perform SHA-256 hashing. Most modern clients, including web applications and mobile apps, can support this method.
    • Example: If the code verifier is xyz123, the client would compute the SHA-256 hash of this string and then base64-url-encode the hash to create the code challenge.

Best Practices

  • Prefer S256: The S256 method is strongly recommended for its enhanced security. By requiring the client to demonstrate possession of the original code verifier (through the transformation), it mitigates the risk of interception and replay attacks.
  • Fallback to Plain: The plain method should only be used if the client environment is unable to perform the necessary hashing operation required by S256.

Specification Reference

These methods are defined in the IETF RFC 7636 (Proof Key for Code Exchange by OAuth Public Clients), which outlines the PKCE extension to the OAuth 2.0 protocol. The specification aims to increase the security for public clients that can't maintain the confidentiality of a client secret.

User Authentication and Authorization Code Issuance

Once redirected to Agile.Now, users authenticate and grant permissions. Agile.Now then returns an authorization code to the specified redirect_uri.

External Authentication with Azure AD or Google

Agile.Now allows integration with external providers like Azure AD or Google OAuth2. The user authenticates with these services, and upon successful authentication, Agile.Now issues the authorization code.

Successful Authorization Response

The response includes the authorization code, state, and nonce:

HTTP/1.1 302 Found
https://acme.com/callback?
code=AuthorizationCode
&state=1234567890
&nonce=NonceValue

Error Response

Error information is communicated back to the redirect URI:

HTTP/1.1 302 Found
https://acme.com/callback?
error=invalid_request
&error_description=ErrorDescription
&state=1234567890

Exchanging Authorization Code for Access Token

After obtaining the authorization code, a POST request is made to /oAuth/rest/v2/Token, including the code verifier (PKCE specific).

Token Exchange Request with PKCE

POST /oAuth/rest/v2/Token HTTP/1.1
Host: login.agilenow.io:443
Content-Type: application/x-www-form-urlencoded

code=AuthorizationCode
&client_id=ClientId
&grant_type=authorization_code
&code_verifier=YourCodeVerifier

Successful Token Response

A successful response includes an access token, an ID token (if the openid scope was requested), and a refresh token:

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "AccessToken",
  "id_token": "IDToken",
  "refresh_token": "RefreshToken"
}

Error Response for Token Exchange

{
   "error": "Unauthorized",
   "error_description": "Client authentication failed.",
   "Errors": [
     "Client authentication failed."
   ],
   "Type": "/Errors/Unauthorized",
   "Title": "Unauthorized",
   "StatusCode": 400,
   "Instance": "/oAuth/rest/v2/Token"
}

Using and Refreshing Tokens

Access tokens are used for API requests. When they expire, the refresh token is used to obtain a new access token from Agile.Now.

PKCE Difference

The key difference in this flow, compared to the standard Authorization Code flow, is the inclusion of the PKCE parameters (code_challenge and code_verifier). PKCE adds an extra layer of security, particularly important for public clients like mobile and desktop apps, by ensuring that the token exchange is done by the same entity that initiated the auth request.


Was this article helpful?