This tutorial will demonstrate how to use the Managed Identity of a Web App to interact with the Graph API and manage the mailbox of a "specific user" using Application permission authorization.
TOC
- Introduction
-
User Management
-
Grant Permission
-
Setup Security Mail Group
-
Test
- References
Introduction
When using the Graph API to manage mail-related services, setting the permission to Delegate permission restricts the authorization to the user’s identity, limiting management to the specific user’s mailbox. While this might not be sufficient for certain business scenarios, Application permission, on the other hand, allows authorization under the App’s identity, enabling access to all users’ mailboxes within the tenant, which could be overly broad for certain use cases.
Therefore, a method is required that allows the management of a specific mailbox using the App’s identity.
This scenario is not recommended to use Delegate permission and requires some prerequisites, which are outlined in this article: Connection Between Web App and O365 Resources: Using SharePoint as an Example.
User Management
In your Microsoft Entra ID tenant, you will need:
- An admin user with permissions to "create users" and "assign roles." This user will perform the following operations. For simplicity, we’ll refer to this user as the admin user.
- An Exchange Administrator user who has the Exchange Administrator role. If not assigned, ensure to assign it to a user. In this example, the user is cch.
- A user account (or multiple users) to be managed by the Web App for mailbox operations. In this example, the user is support.
Additionally, remember to visit https://admin.microsoft.com/ to assign a Microsoft 365 license to the new user, enabling mailbox access.
Grant Permission
For this example, we’ll use Managed Identity to grant the Mail.ReadWrite permission to the Enterprise Application corresponding to the Web App's Managed Identity.
Note: Depending on your business requirements:
- You can replace the Managed Identity with a Multi-Tenant App Registration.
- You can also adjust Mail.ReadWrite to other permissions aligned with your business needs.
Log in to the Azure Portal with your admin user and open a PowerShell CloudShell session. Modify and run the following commands to grant the necessary Graph API permissions to the Web App’s Managed Identity.
Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All"
$PrincipalId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Please setup your Managed Identity's OBJ ID
$ResourceId = (Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'" | Select-Object -ExpandProperty Id)
$AppRoles = Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'" -Property AppRoles |
Select -ExpandProperty AppRoles |
Where-Object { $_.Value -like "Mail.ReadWrite" } # Please setup your permission
$AppRoles | ForEach-Object {
$params = @{
"PrincipalId" = $PrincipalId
"ResourceId" = $ResourceId
"AppRoleId" = $_.Id
}
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $PrincipalId -BodyParameter $params
}
Setup Security Mail Group
Log in to the Azure Portal with an Exchange Administrator user, open a PowerShell CloudShell session, and run the following commands:
- Create a Security Mail Group.
- Add the mailboxes (e.g., support) that need to be accessible via the Web App to the group.
- Associate the Managed Identity's authorization with the Security Mail Group.
az login --tenant XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX--use-device-code # Please setup your tenant id
Connect-ExchangeOnline
Connect-AzureAD
New-DistributionGroup -Name "Policy Scope Group" -Alias "policy-scope-group" -Type Security
Add-DistributionGroupMember -Identity "Policy Scope Group" -Member "XXX@XXX.com" # Please setup your receiver mailbox
$AppId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Please setup your Managed Identity's APP ID
$GroupId = (Get-AzureADGroup -SearchString "Policy Scope Group" | Select-Object ObjectId).ObjectId
New-ApplicationAccessPolicy -AppId $AppId -PolicyScopeGroupId $GroupId -AccessRight RestrictAccess
Important Notes
- Allow at least one hour for all configurations to take effect.
- Ensure the Microsoft 365 license has been assigned to the relevant user(s).
Test
You can deploy the following example code to your Web App. Replace support@xx.com with the mailbox to be accessed programmatically, and prepare another mailbox (e.g., cch@xx.com) for testing to ensure that only mailboxes within the Security Mail Group can be accessed.
import requests
from azure.identity import ManagedIdentityCredential
def get_access_token():
credential = ManagedIdentityCredential()
token = credential.get_token("https://graph.microsoft.com/.default")
return token.token
def get_latest_email_subject(target_email):
access_token = get_access_token()
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
url = f"https://graph.microsoft.com/v1.0/users/{target_email}/mailFolders/Inbox/messages?$count=true"
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
if "value" in data and len(data["value"]) > 0:
return data["value"][0].get("subject", "No Subject")
else:
print("No emails found in the inbox.")
return None
else:
print("Failed to fetch emails.")
print("Status Code:", response.status_code)
print("Response:", response.json())
return None
if __name__ == "__main__":
print("=============================================")
print("Fetching support@xx.com's latest email subject...")
target_email = "support@xx.com"
subject = get_latest_email_subject(target_email)
if subject:
print("Latest Email Subject:", subject)
else:
print("No email subject found.")
print("=============================================")
print("Fetching cch@xx.com's latest email subject...")
target_email = "cch@xx.com"
subject = get_latest_email_subject(target_email)
if subject:
print("Latest Email Subject:", subject)
else:
print("No email subject found.")
After testing, you should observe that only the mailboxes of members within the Security Mail Group can be accessed by the Web App, while other mailboxes remain inaccessible. This ensures secure and specific access control.
References
Microsoft Graph permissions reference - Microsoft Graph | Microsoft Learn