The Authorization Code Flow with Proof Key for Code Exchange (PKCE) is a recommended OAuth 2.0 flow for native apps. No client secret is required in this flow. Instead, a secret is created by the calling application that can be verified by the authorization server.

The example application requests an authorization code, redeems the code for an access token, and then calls the Microsoft Graph API to retrieve user profile data, and to send an email on behalf of the signed-in user.

Software requirements

Entra App registration configuration

The example code uses an existing Microsoft Entra App registration. You may use your own Entra App registration by setting the CLIENT_ID in unit MainUnit:

procedure Demo;
const
  TOKEN_ENDPOINT = ...;
  AUTHORIZE_ENDPOINT = ...;
  // Application (client) ID from Entra configuration
  CLIENT_ID = '8e03cfb2-2cd2-48fd-b7b5-789ad1c13fd2';

Email configuration

The content and recipient of the email is configured in a JSON document in unit RootResource.

Unit overview

UnitDescription
MainUnitThe main Demo procedure creates and configures the web application and starts the local web server. Then it launches the default web browser and sends a request to http://127.0.0.1/index.html.
AuthFilterConfigured to process all requests for HTML pages.
TAuthFilter.DoFilter checks if the current session has already acquired an access token. If not, it initiates the flow by sending the authorize request to the authorization endpoint at Microsoft Entra ID.
AuthResponseResourceConfigured to handle HTTP POST requests for the callback URI http://127.0.0.1/auth-response.
The OnPost handler reads the authorization code from the POST request, uses the token endpoint to redeem the code for an access token (OAuth bearer token), and then stores the access token in the current session. The request then is redirected to the index.html page.
RootResourceConfigured to handle HTTP GET requests for /index.html.
The OnGet handler reads the access token from the session, and uses it as the OAuth bearer token to perform Graph API calls.

Note on client secrets

  • The example does not need a “client secret”. Therefore it is fit to use in mobile and desktop applications.
    • “Don’t use the application secret in a native app or single page app because a client_secret can’t be reliably stored on devices or web pages. It’s required for web apps and web APIs, which can store the client_secret securely on the server side.” (source)
    • This can be seen in the “Certificates & secrets” page of the App registration:
  • The example uses PKCE (“Proof Key for Code Exchange”) to prevent CSRF and authorization code injection attacks.

Note on API permissions

  • The example does not request an refresh token. This can be seen in the “API permissions” page of the App registration:

Recommended articles

Trademarks

Microsoft and Microsoft Entra ID are trademarks of the Microsoft group of companies.

Leave a comment