MS Graph ROPC Auth Flows
Motivation
As of 12/31/2022, Microsoft disabled PLAIN/SASL authentication for IMAP and POP protocol access to mailboxes in Office 365 (even over TLS ), and they have made it clear that SMTP is next. In fact, they likely would have already disable SASL for SMTP were it not for the volumes that they see flowing through that protocol from even such lowly things as multi-function printers / scanners.
Knowing that SMTP will lose access to SASL authentication at some unknown point in the (possibly near) future, and having already lost IMAP access, I needed to dive into the situation and sort out how to make XOAUTH2 authentication work for those protocols, that we use routinely in our software as a service businesses. I did that, figured it all out, determined what I felt was the best approach for us and our customers, and then wrote this blog post to document it and to share it so that it may help others.
Use Cases
The types of use cases that this document targets are those where an application needs to send (and possibly also receive) emails to/from a given O365 email address that is associated with a user account. Common scenarios are things like ticketing systems that may control an email address such as support@myco.com. It has long been common in those situations to have the app send emails via SMTP through outlook.office365.com and to receive emails using IMAP or POP. Prior to 12/31/2022, all three of those protocols could use user credentials (username/password) and SASL over TLS for authentication, but that is no longer allowed for IMAP and POP.
On a go-forward basis, these types of applications must send/receive emails by either using the MS Graph Mail APIs directly, with authentication via OAUTH2 , or authenticate to IMAP/POP/SMTP using token-based authentication and XOAUTH2 .
Options
To my knowledge, there are two practical ways to accomplish this:
- The method that Microsoft recommends that seems unwise to me, and
- The method described herein, that we chose to move forward with.
Option 1: Workload Identities
Using Workload identities seems to be the preferred method recommended by Microsoft and described in tutorials that address these types of use cases. Workload identities provide authorization directly to registered applications that use shared secrets (or certificates) to authenticate themselves at an “application level” with an OAUTH2 grant_type of client_credentials, and then operate on resources owned by users. There are many tutorials on how to do this, and I linked to one below. In short, you create a registered application, assign a secret or certificate to it that it uses for authentication, and then give it carte blanche permission to access certain resources (email in this case) for all users! After that, and using some Powershell commands, you can create an application access policy in Exchange Online that will limit the app’s permissions scope to a certain groups’ or users’ mailboxes.
This is one of many tutorials on the workload identities method . And to be clear, this guy knows what he is doing, but if you pay attention, that procedure gives a registered application complete and total access to every users’ mailbox in an entire O365 tenant and then, afterwards and with Powershell commands, the app is restricted to one group inside of Exchange Online. And to be even more clear, the guy isn’t touting anything that Microsoft isn’t: Quoted from https://learn.microsoft.com/en-us/graph/auth-limit-mailbox-access
- “For example, the Mail.Read application permission allows apps to read mail in all mailboxes without a signed-in user.”
Option 2: Resource Owner Password Credentials (ROPC)
Unlike workload identities, the ROPC authentication flow allows an application to authenticate itself as an actual, individual user (resource owner), just like these style of email applications have been doing via username and password credentials with SASL over TLS for a very long time. But, it is done by way of a OAUTH2 process to generate a Bearer Token with the grant_type of password.
To facilitate ROPC authentication flows, you must create an “App registration” in the O365 tenant, but the app needs no certificates or secrets because it will be using the actual credentials of the target user. The app will need a set of API permissions that correspond to what it is allowed to do (see table below), and for convenience you will probably want to “Grant admin consent” for all of them. At that point, the app can use the ROPC authentication flow to login as any user by using their username and password with its application ID (client_id), and perform any of the actions allowed by its API permissions. But note, the app can log in as one and only one user at a time and it requires their credentials (username/password) to do so. It does not have carte blanche access to all users’ information with a single app secret that is then limited down with a Powershell command. Moreover, there is an Enterprise Applications option to limit the app to only certain users, that we will use (instructions below) to limit it to only one or very few user accounts.
And so, several important things are true about the ROPC method:
- You never create a secret-credentialed app with “all user” authority, that you then restrict with Powershell commands.
- The app uses user credentials which can be set to never expire, unlike app secrets which max out at 2 years.
- Using the GUI Enterprise Applications tools, you can set the app to have “Assignment required” and then assign to it only the users that you want to allow it access to.
- You can also run Exchange Powershell commands to restrict the app to just a single user or group, as in the Workload Identities method, but that truly is not needed.
The “credentials” that you will use (or share with a vendor) are three-fold:
- Your Office 365 Tenant ID.
- The Registered App’s Client ID.
- Username and Password of the mailbox owning user.
And also if desired, in the Exchange admin center under General -> Manage email apps for the user, you can disable Outlook, Exchange web services, ActiveSync, and POP, leaving on only IMAP and SMTP.
Note that ROPC flows cannot be used on accounts with MFA enabled. This should not be a problem as existing accounts that were being accessed in the past via POP, IMAP, or SMTP had the same limitation.
Sample Of Related App API Permissions
# | Capability | API Permission needed |
---|---|---|
1. | Get an auth token via the ROPC flow | User.Read |
2. | Read the user’s calendar | Calendars.Read |
3. | Read the user’s mailFolders | Mail.Read |
4. | Send mail with the Graph API | Mail.Send |
5. | Send mail via SMTP auth’ed w/XOAUTH2 | SMTP.Send |
6. | Use IMAP authenticated with XOAUTH2 | IMAP.AccessAsUser.All |
Step-by-Step Configuration Guide for ROPC
In this section, creating a user and the user’s mailbox is outside of the scope of what I cover, as is creating an “ App registration ” although I cover all of the details of the requisite setting for the registered app.
And so, register an app that you will use for this and then follow along through the next sections to see how to configure things…
App Registration: Authentication
On the Authentication tab, you can set the Supported account types to “this organizational directory only” since we plan to authenticate as a user from within it, and within the Advanced settings you must “Enable the following mobile and desktop flows” that include ROPC.
App Registration: API Permissions
On the API permissions tab you will want to + Add a permission and then choose Microsoft Graph and then choose Delegated permissions and then navigate through to select the appropriate permissions, as described in the table above and shown in the screenshot here. After adding all of the permissions that are needed, you’ll almost certainly want to ✓ Grant admin consent which means that the users (just one when we’re done) will have these permissions pre-granted, thus avoiding need for user consent via the delegated permissions process .
App Registration: Certificates and Secrets
I included this section and this screenshot just to make the point that this registered application needs no certificates or secrets as it does not authenticate as itself (app), but rather as a user. As mentioned prior, this also avoids the problem with secrets expiring at least every two years.
Enterprise App: Assignment Required?
This step and the next combine to limit the application to only be allowed to authenticate as one user. First, we change the value of Assignment required? on the Properties tab to Yes, and as soon as you do that no user will be able to use this app (except the admin owner/creator).
Enterprise App: Users and Groups
Now use the Users and groups tab’s +Add user/group and add the user that you wish to have this app operate as. In the screenshot here, you will see two users:
- Me, the admin who created this registered app, and
- Portaldemo Email, the user whose email box this app will operate on.
This step and the prior one are documented by Microsoft here: https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-restrict-your-app-to-a-set-of-users
Exchange Admin Center: Manage Email Apps
This last step is truly optional, but if you want to limit possible exposure to this account even further, you can limit most of the typical ways that a user would interact with this email box. In the screenshot just below, I left “Outlook on the web” enabled since we may login to the mailbox that way from time to time, and I left IMAP on because that is one of the use cases for this email box, but I turned all others off.
Outro
I hope that this article was helpful and informative. Despite Microsoft discouraging the use of ROPC, I truly believe that it is the safest and least error-prone of the two practical methods to accomplish this type of application-based email account access, and it requires no Powershell work.
Postcript
Demonstrating how to actually use ROPC to access various O365 mailbox-related services is beyond the scope of this blog post, but I placed the code that I used to work through all of this into a GitHub gist. That code should allow you to test/demo all of the protocols discussed in this article.