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
- Daraja HTTP Framework (https://github.com/michaelJustin/daraja-framework). The example code is located in the entra_auth_code_flow folder.
- Indy (https://github.com/IndySockets) with OpenSSL DLLs for Indy (https://github.com/IndySockets/OpenSSL-Binaries)
- JsonDataObjects (https://github.com/ahausladen/JsonDataObjects)
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
Unit | Description |
---|---|
MainUnit | The 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 . |
AuthFilter | Configured 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. |
AuthResponseResource | Configured 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. |
RootResource | Configured 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
- OAuth 2.0 for Native Apps (rfc8252)
- Proof Key for Code Exchange by OAuth Public Clients (rfc7636)
- Microsoft identity platform and OAuth 2.0 authorization code flow
- OAuth 2.0 authorization with desktop application
- Which OAuth 2.0 Flow Should I Use?
Trademarks
Microsoft and Microsoft Entra ID are trademarks of the Microsoft group of companies.