azuremicrosoft-graph-apiazureportalazure-authentication

Only allow accessing emails from users assigned to Azure Enterprise Application using Confidential Client Credential Flow


I have an application where I want to send and read emails for a specific list of users assigned to an Azure Enterprise Application using the MS Graph API and the Confidential Client Credential flow. I do not know which users these will be initially, but I can query them through the service principals endpoint for the application and let the application user pick which one(s) to use.

I understand that I need to add the Application level User.Read.All, Mail.Send, and Mail.Read API permissions to the App registration and grant admin consent for them, however after retrieving the confidential client token and calling the https://graph.microsoft.com/v1.0/users/{user}/sendMail endpoint with it, I find it will still let me send from any user in the domain and not just the ones assigned to the application. The Assignment required setting in the enterprise application properties doesn't appear to affect this.

Is there a way to ensure the endpoint cannot be used to send/read user emails that are not assigned to the enterprise application?


Solution

  • I created an Azure AD application and granted API permissions like below:

    enter image description here

    And set Assignment required as YES in the Enterprise application:

    enter image description here

    For sample added ruk user:

    enter image description here

    Now I generated access token using Client Credentials flow by using below parameters via Postman:

    https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
    
    client_id:ClientID
    client_secret:ClientSecret
    scope:https://graph.microsoft.com/.default
    grant_type:client_credentials
    

    enter image description here

    By using the above access token, I tried to send mail by another user which is not assigned to the Enterprise application. And I am able to send mail successfully:

    POST https://graph.microsoft.com/v1.0/users/usertest@xxx.onmicrosoft.com/sendMail
    Content-type: application/json
    
    {
      "message": {
        "subject": "Meet for lunch?",
        "body": {
          "contentType": "Text",
          "content": "The new cafeteria is open."
        },
        "toRecipients": [
          {
            "emailAddress": {
              "address": "user@xxx.onmicrosoft.com"
            }
          }
        ],
        "ccRecipients": [
          {
            "emailAddress": {
              "address": "user1@xxx.onmicrosoft.com"
            }
          }
        ]
      },
      "saveToSentItems": "false"
    }
    

    enter image description here

    Note that: If you are setting Assignment required to YES then it works for only User Sign-in scenario or User interactive flow not for Confidential Client Credential Flow as there is no user interaction involved.

    For Client Credential Flow/Application identity scenario, you must configure Application Access Policy like below:

    Connect-ExchangeOnline
    
    New-ApplicationAccessPolicy -AppId ClientID -PolicyScopeGroupId ruk@xxx.onmicrosoft.com -AccessRight RestrictAccess -Description "test"
    

    enter image description here

    You can test the policy against other users:

    Test-ApplicationAccessPolicy -Identity user@xxx.onmicrosoft.com -AppId ClientID
    
    Test-ApplicationAccessPolicy -Identity ruk@xxx.onmicrosoft.com -AppId ClientID
    

    enter image description here

    Now only the ruk user will be able to send mail using the access token generated by Client Credential flow for the application.

    References:

    How to allow Azure Ad App to access information only for certain users? - Microsoft Q&A by krish-gh

    New-ApplicationAccessPolicy (ExchangePowerShell) | Microsoft