Authenticate an IMAP connection using OAuth 2.0

 

To authenticate your IMAP connection using OAuth 2.0 Please follow the below steps

  1. Register your application with Azure AD. 
  2. Get access tokens from a token server. 
  3. Authenticate connection requests with an access token.


1. Register an application

Registering your application establishes a trust relationship between your app and the Microsoft identity platform. The trust is unidirectional: your app trusts the Microsoft identity platform, and not the other way around. 


Follow these steps to create the app registration:

  1. Sign in to the Azure portal. 
  2. If you have access to multiple tenants, use the Directories + subscriptions filter in the top menu to switch to the tenant in which you want to register the application. 
  3. Search for and select Azure Active Directory. 
  4. Under Manage, select App registrations > New registration. 
  5. Enter a display Name for your application. Users of your application might see the display name when they use the app, for example during sign-in. You can change the display name at any time and multiple app registrations can share the same name. The app registration's automatically generated Application (client) ID, not its display name, uniquely identifies your app within the identity platform. 
  6. Specify who can use the application, sometimes called its sign-in audience
  7. Don't enter anything for Redirect URI (optional). You'll configure a redirect URI in the next section. 

  8. Select Register to complete the initial app registration. 


Supported account types Description
Accounts in this organizational directory only Select this option if you're building an application for use only by users (or guests) in your tenant. 
 
Often called a line-of-business (LOB) application, this app is a single-tenant application in the Microsoft identity platform.
Accounts in any organizational directory Select this option if you want users in any Azure Active Directory (Azure AD) tenant to be able to use your application. This option is appropriate if, for example, you're building a software-as-a-service (SaaS) application that you intend to provide to multiple organizations. 
 
This type of app is known as a multitenant application in the Microsoft identity platform.
Accounts in any organizational directory and personal Microsoft accounts Select this option to target the widest set of customers. 
 
By selecting this option, you're registering a multitenant application that can also support users who have personal Microsoft accounts. 
Personal Microsoft accounts Select this option if you're building an application only for users who have personal Microsoft accounts. Personal Microsoft accounts include Skype, Xbox, Live, and Hotmail accounts. 

 

Register service principals in Exchange 

To use the New-ServicePrincipal cmdlet, install the ExchangeOnlineManagement and connect to your tenant in PowerShell cmd.  


Install-Module -Name ExchangeOnlineManagement -allowprerelease 
Import-module ExchangeOnlineManagement  
Connect-ExchangeOnline -Organization <tenantId>  


The following is an example of registering an Azure AD application's service principal in Exchange: 

New-ServicePrincipal -AppId <APPLICATION_ID> -ServiceId <OBJECT_ID> [-Organization <ORGANIZATION_ID>]  


You can get your registered service principal's identifier.  

Get-ServicePrincipal | fl 


The tenant admin can now add the specific mailboxes in the tenant that will be allowed to be access by your application. This is done with the Add-MailboxPermission cmdlet. 

The following is an example of how to give your application's service principal access to one mailbox: 


Add-MailboxPermission -Identity "test.user@enzigma.com" -User  

<SERVICE_PRINCIPAL_ID> -AccessRights FullAccess 


Note:  service_id should be an object_id of the enterprise application.  


Add credentials  

Credentials are used by confidential client applications that access a web API. Examples of confidential clients are web apps, other web APIs, or service-type and daemon-type applications. Credentials allow your application to authenticate itself, requiring no interaction from a user at runtime. 


You can add both certificates and client secrets (a string) as credentials to your confidential client app registration. 


Add a certificate  

Sometimes called a public key, a certificate is the recommended credential type because they're considered more secure than client secrets. For more information about using a certificate as an authentication method in your application, see Microsoft identity platform application authentication certificate credentials.  

  1. In the Azure portal, in App registrations, select your application. 
  2. Select Certificates & secrets > Certificates > Upload certificate. 
  3. Select the file you want to upload. It must be one of the following file types: .cer.pem.crt. 
  4. Select Add.
 

Add a client's secret 

Sometimes called an application password, a client secret is a string value your app can use in place of a certificate to identify itself. 

Client secrets are considered less secure than certificate credentials. Application developers sometimes use client secrets during local app development because of their ease of use. However, you should use certificate credentials for any of your applications that are running in production. 

  1. In the Azure portal, in App registrations, select your application. 
  2. Select Certificates & secrets > Client secrets > New client Secrets. 
  3. Add a description of your client's secret. 
  4. Select an expiration for the secret or specify a custom lifetime. 
    • The client's secret lifetime is limited to two years (24 months) or less. You can't specify a custom lifetime longer than 24 months. 
    • Microsoft recommends that you set an expiration value of less than 12 months.  
  5. Select Add. 
  6. Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.
2. Get an access token   

You can use one of our MSAL client libraries to fetch an access token from your client application. 


Alternatively, you can select an appropriate flow from the following list and follow the corresponding steps to call the underlying identity platform REST APIs and retrieve an access token.

  1. OAuth2 client credentials grant flow
    1. Create an abstract class and add a method that will return an access token by using client_id, client_secret, authority, and scope of your application. 

      Code example: 

          public static IAuthenticationResult acquireToken() { 

              IAuthenticationResult accessToken = null; 

              final User _userClient = null; 

              try { 

                  String CLIENT_ID = " client_id of your app"; 

                  String CLIENT_SECRET = “client secret of your app"; 

                  String AUTHORITY = "https://login.microsoftonline.com/{tenant_id}/v2.0"; 

                  Set<String> SCOPE = new HashSet<String>(); 

                  SCOPE.add("https://outlook.office365.com/.default"); 

                  // This is the secret that is created in the Azure portal when registering the application 

                  IClientCredential credential = ClientCredentialFactory.createFromSecret(CLIENT_SECRET); 

                  ConfidentialClientApplication cca 

                          = ConfidentialClientApplication 

                                  .builder(CLIENT_ID, credential) 

                                  .authority(AUTHORITY) 

                                  .build(); 

                  ClientCredentialParameters parameters 

                          = ClientCredentialParameters 

                                  .builder(SCOPE) 

                                  .build(); 

                  accessToken = cca.acquireToken(parameters).join(); 

              } catch (Exception e) { 

                  System.out.println("Exception in acquiring token: " + e.getMessage()); 

                  e.printStackTrace(); 

              } 

              return accessToken; 

          } 


      Also, can get access tokens by sending a request through postman:



      Make sure to specify the full scopes, including Outlook resource URLs, when authorizing your application and requesting an access token.


      Protocol Permission scope string 
      IMAPhttps://outlook.office.com/IMAP.AccessAsUser.All



      In addition, you can request offline_access scope. When a user approves the offline_access scope, your app can receive refresh tokens from the Microsoft identity platform token endpoint. Refresh tokens are long-lived. Your app can get new access tokens as older ones expire.
3. Authenticate connection request with an access token.  

You can initiate a connection to Office 365 mail servers using the IMAP.

 

Access Token Passing: 


Pass access token rather than password in store.connect() method.

 

connection using OAuth: 

store.connect(host, user, password); 


Note: 

Before authenticate using store.connect() method, need to notify to mail server that we are authenticating through OAuth 2.0 by setting the properties. 

Example:  

            Properties props = new Properties (); 

            props.setProperty("mail.debug.auth", String.valueOf(true)); 

            props.setProperty("mail.debug", "true"); // to see the debug logs during                                                        authentication.  

            props.put("mail.imaps.auth.mechanisms", "XOAUTH2"); 

            props.put("mail.imaps.sasl.mechanisms", "XOAUTH2"); 

            props.put("mail.imaps.auth.login.disable", "true"); 

            props.put("mail.imaps.auth.plain.disable", "true"); 

 

connection using OAuth 2.0: 

store.connect(host, user, access_token); 

Sample client-server message exchange that results in an authentication success: 

[connection begins] 
C: C01 CAPABILITY 
S: * CAPABILITY … AUTH=XOAUTH2 
S: C01 OK Completed 
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cBAQ== 
S: A01 OK AUTHENTICATE completed. 
 

Sample client-server message exchange that results in an authentication failure: 

[connection begins] 
S: * CAPABILITY … AUTH=XOAUTH2 
S: C01 OK Completed 
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cBAQ== 
S: A01 NO AUTHENTICATE failed.