Three Steps to Send SMTP Mails via Exchange Online with OAuth2 Authorization and Object Pascal

Where do we want to go today?

Sending emails through Exchange Online using OAuth2 can be a robust, secure alternative to traditional username/password authentication. This post outlines how to achieve this in Object Pascal (Free Pascal / Lazarus or Delphi) using the Indy components (TIdHTTP and TIdSMTP), broken down into three practical steps:

Step 1: Configure Exchange Online and Register an Entra ID App

Delphi SMTP with OAuth2 app registration

Before sending emails via Delphi SMTP with OAuth2, you need to set up the Microsoft 365 tenant to support token-based authentication.

  • Register an app in Entra ID (formerly Azure AD):
    • Navigate to Azure Portal > Entra ID > App registrations.
    • Click New registration, assign a name, and leave the redirect URI blank (for native apps).
    • Record the Application (client) ID and Tenant ID.

To allow your app to send email on behalf of users or as itself, configure Application permissions for Exchange Online SMTP:

  • Configure Application permissions
    • In the Azure Portal, go to Azure Active Directory > App registrations, and select your app.
    • Navigate to API permissions > Add a permission.
    • Under APIs my organization uses, search for and select Office 365 Exchange Online.
    • Add the permission:
      • DelegatedSMTP.Send
    • Optionally, add offline_access under Microsoft Graph (for refresh tokens).

  • Grant Admin Consent
    • Still in API permissions, click Grant admin consent for [Organization].
      • Note: Admin consent is required for Application permissions to take effect.
      • Allow SMTP AUTH for the Mailbox (Optional, if disabled globally) Some tenants have SMTP AUTH disabled by default. You may need to enable it.

  • Generate a client secret
    • Under Certificates & secrets, add a new client secret and copy its value.
    • Enable SMTP AUTH for the mailbox (if disabled by default):
      • You can use PowerShell or the Microsoft 365 Admin Center to verify and enable SMTP AUTH.

Disclaimer: I have not yet been able to verify these configuration steps, as I currently do not have access to an Exchange Online license.

Step 2: Acquire an OAuth2 Access Token Using Indy TIdHTTP


Once the Entra ID app is registered, you can use Indy’s TIdHTTP component in Object Pascal to perform the token request.

  • Build the token request using the client credentials or resource owner password grant (depending on the chosen flow).
  • Use TIdHTTP.Post with appropriate headers and TIdSSLIOHandlerSocketOpenSSL for HTTPS.
  • Parse the JSON response to extract the access_token.

Example code outline:

// Token request using TIdHTTP
// POST to https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token

HTTP.Request.ContentType := 'application/x-www-form-urlencoded';

RequestBody.Add('grant_type=client_credentials');
RequestBody.Add('client_id=' + ClientID);
RequestBody.Add('client_secret=' + ClientSecret);
RequestBody.Add('scope=' + Scope);

Result := HTTP.Post(TokenEndpoint, RequestBody);

Make sure you include:

  • client_id
  • client_secret
  • scope (e.g., https://outlook.office365.com/.default)
  • grant_type (e.g., client_credentials)

Step 3: Send Email Using Indy TIdSMTP with OAuth2 Access Token

With the access token in hand, you can now use TIdSMTP to send mail via Exchange Online’s SMTP endpoint (smtp.office365.com).

  • Set up the TIdSMTP and TIdMessage components.
  • Configure the TIdSMTP.AuthType to use satSASL and attach a TIdSASLXOAuth2 instance.
  • Provide the OAuth2 token via the SASL mechanism instead of a password.

Sample configuration:

UserPass := TIdUserPassProvider.Create(IdSMTP);
UserPass.Username := 'info@habarisoft.com';
UserPass.Password := Base64EncodedToken;

Auth := IdSMTP.SASLMechanisms.Add;
Auth.SASL := TIdSASLXOAuth2.Create(IdSMTP);
TIdSASLXOAuth2(Auth.SASL).UserPassProvider := UserPass;

IdSMTP.UseTLS := utUseExplicitTLS;
IdSMTP.AuthType := satSASL;
IdSMTP.Connect;

IdSMTP.Authenticate;
IdSMTP.Send(IdMessage);  

Conclusion

By following these three steps—configuring Exchange Online, retrieving an OAuth2 token, and setting up SMTP with Indy components—you can send authenticated emails from an Object Pascal application without relying on less secure legacy credentials. This approach improves security and aligns with Microsoft’s modern authentication requirements.

GitHub Project

GitHub Repository: Delphi SMTP With OAuth2

https://github.com/michaelJustin/delphi-smtp-with-oauth2

The project has been created with Lazarus 4 / Free Pascal 3.2.2 in Delphi compatibility mode and uses Indy 10.6.3.10. It requires the 64 Bit OpenSSL DLLs from the Indy Repository https://github.com/IndySockets/OpenSSL-Binaries

Work in Progress

Send secure SMTP email from Delphi applications

Daraja HTTP Server Framework : Microsoft Entra ID example for OpenID Connect Refresh Token