Microsoft Graph — Email Access
TL;DR; After this article, you will be able to Read and modify a users O365 mailbox contents using Microsoft Graph.
Intro
Microsoft Graph is one of the best little jewels that Microsoft has delivered in years. Still, it’s somewhat unknown what it can be used for, and how to properly configure it. This article will try to shed some light on how to do this. Once you understand how valueble it is, you’re also going to use it :)
Prerequsites
You need to have the following:
- Name and password of the account to read (and write) emails on (eg user1@contoso.com)
- Also, the same account should have suffient rights on to register applications.
- You also need a notepad, there’s a ton of items to keep track of
Registering an application
- Login as the user you intend to access as (user1@contoso.com)
- Open the App Registrations on Azure.
- Register a new Application and give it a name (for example “api-mail-processor”)
- Choose Application Type. If you don’t know, use “Web” and enter “http://localhost/” for now.
Important! Make a exact copy of this address including ending slashes. Everything must match perfectly below.
Configure the Application Permissions
Now, this might seem like a simple task, but it’s not. Many of the rights is “Admin Consent” which means you need a high-level access account at hand. Also, IMHO this encourages bad security behaviour — it’s better to try to stay on user level as much as possible. Now, this will have one impact though, your piece of software will only have the ability to login as a User (using a User Access Token). Trying to login as an background service (grant_type=client_credentials) will not work.
So, add permissions. Click “API Permissions”, then “Add a permission” and finally “Microsoft Graph”.
Again, if you’re writing a background service, it’s tempting to click “Application Permissions”, but this guide focuses on Delegated Permissions.
Add the “Mail.Read” and the “Mail.ReadWrite”. Note that Admin Consent is not required.
Write down the rights you’ve decided to use (Mail.Read, Mail.ReadWrite). This will render the following rights:
Next, we want to enable an Client Secret.
Click Certificates and secrets, then “new client secret”. Give it a name and click “Add”.
Copy the Secret ID and Secret Value for later use.
Next, copy the rest of important information. Open “Overview” and copy “Application (client) ID”, “Directory (tenant) ID” and “Object ID”
Finally open “Endpoints” and copy the “OAuth 2.0 autorization endpoint”
Consent time
The user (owner) of the mailbox must consent the app to access the emails. In order to do that, the user opens a link and clicks “Consent.”.
Important! Every time you change the permissions for the app, the user must consent to the change!
Manually build the following URL. {{the rights}} is the “Mail.Read Mail.ReadWrite” (with a space between each requested right).
https://login.microsoftonline.com/{{tenantID}}/oauth2/v2.0/authorize?client_id={{clientID}}&response_type=code&redirect_uri={{theURL}}&response_mode=query&scope=offline_access%20{{the rights}}&state={{a random number}}
For the app built here:
https://login.microsoftonline.com/{{tenantID}}/oauth2/v2.0/authorize?client_id={{clientID}}&response_type=code&redirect_uri=http://localhost/&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345
As the user (user1@contoso.com) opens this link, the following dialog will appear:
After the user has accpted, they’re redirected to the “redirect_uri”, which in our example is localhost. There’s probably nothing there to answer, so an error will appear. To make the user experience better, this needs to be fixed by changing in the App Registrations > Authentication > Web > Edit URI.
Postman Time
Begin with authenticating, which will give the well-needed access_token. In order to achive this step, you need to have TenantID, ClientID, ClientSecret, the requested Scopes, the Username and the Users password.
POST https://login.microsoftonline.com/{{tenantID}}/oauth2/v2.0/tokengrant_type=password&client_id={{clientID}}&client_secret={{clientSecret}}&scope={{the rights}}&userName={{username}}&password={{password}}
Postman screenshot:
Request as HTTP:
POST https://login.microsoftonline.com/{{tenantID}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencodedgrant_type=password&client_id={{clientID}}&client_secret={{clientSecret}}&scope=Mail.Read Mail.ReadWrite&userName=user1@contoso.com&password={{password}}
.. and the response should look like this. Copy the access_token.
Getting the emails…
Finally the emails can be fetched:
GET https://graph.microsoft.com/v1.0/users/{{username}}/messages
Authorization: Bearer {{access_token}}
For this app:
GET https://graph.microsoft.com/v1.0/users/user1@contoso.com/messages
Authorization: Bearer {{access_token}}
… or slightly more advanced:
GET https://graph.microsoft.com/v1.0/users/user1@contoso.com/messages?$filter=isRead ne true&$top=50
Authorization: Bearer {{access_token}}
Modifying Emails?
Since the requested rights included write access, many attributes of the email can be changed. Like “isRead” or “subject”.
PATCH https://graph.microsoft.com/v1.0/users/{{username}}/messages/${iMessageID}
Authorization: Bearer {{access_token}}
Content-Type: application/json{
"subject": "New subject on an email!"
}
More information
- The graph explorer can be used to browse the entire catalog of functions: https://developer.microsoft.com/en-us/graph/graph-explorer
- A Postman collection ready for importing can be found here: https://github.com/microsoftgraph/microsoftgraph-postman-collections
Enjoy
:)