如何在 MVC 应用程序中使用 Microsoft Graph 访问其他用户的资源(特别是电子邮件)?

Luc*_*n P 2 c# asp.net-mvc azure azure-active-directory microsoft-graph-api

我似乎在为我的应用程序授予访问组织电子邮件中的另一个用户所需的权限时遇到问题。我让我的管理员通过 Azure 门户授予我的应用程序所有可能的权限,并且我在从 Graph 网站下载的测试应用程序中收到“访问被拒绝”错误。这让我觉得我可能没有使用正确的 API 调用。

这是我用来检索另一个用户的电子邮件的代码:

IMailFolderMessagesCollectionPage messages = await graphClient.Users["userID"].MailFolders.Inbox.Messages.Request().Top(25).GetAsync();
Run Code Online (Sandbox Code Playgroud)

其中“userID”是我通过图形浏览器获取组织中所有用户获得的 id 值。

完整代码:

(控制器)

[Authorize]
public async Task<ActionResult> GetEmails()
        {
        try
        {
            // Initialize the GraphServiceClient.
            GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient();

            ResultsViewModel results = new ResultsViewModel();
            // Get the messages. 
            results.Items = await graphService.GetMyInboxMessages(graphClient);
            return View("Graph", results);
        }
        catch (ServiceException se)
        {
            if (se.Error.Code == Resource.Error_AuthChallengeNeeded) return new EmptyResult();
            return RedirectToAction("Index", "Error", new { message = Resource.Error_Message + Request.RawUrl + ": " + se.Error.Message });
        }
    }
Run Code Online (Sandbox Code Playgroud)

(graphService.cs)

public async Task<List<ResultsItem>> GetMyInboxMessages(GraphServiceClient graphClient)
    {
        List<ResultsItem> items = new List<ResultsItem>();

        // Get messages in the Inbox folder. 
        //IMailFolderMessagesCollectionPage messages = await graphClient.Me.MailFolders.Inbox.Messages.Request().GetAsync();  
        IMailFolderMessagesCollectionPage messages = await graphClient.Users["e87151ce-093b-4820-a98c-4cef247ed2be"].MailFolders.Inbox.Messages.Request().Top(25).GetAsync();

        string recipients = string.Empty;
        if (messages?.Count > 0)
        {
            foreach (Message message in messages)
            {
                //foreach (Recipient recipient in message.ToRecipients)                    
                for (int i = 0; i < message.ToRecipients.Count(); i++)
                    recipients += ((i != 0 ? "; " : "") + message.ToRecipients.ElementAt(i).EmailAddress.Address.ToString());

                items.Add(new ResultsItem
                {
                    Type = "message",
                    SentDateTime = message.SentDateTime.Value.DateTime.ToLocalTime(),
                    Subject = message.Subject,
                    From = message.From.EmailAddress.Address.ToString(),
                    To = recipients,
                    Id = message.Id,
                    Body = message.Body.Content.ToString()
                });
            }
        }
        return items;
    }
Run Code Online (Sandbox Code Playgroud)

这是一个不正确的 GET 请求吗?还是权限问题?

在此先感谢您的帮助。

Nan*_* Yu 5

您可以使用Read mail in all mailboxes应用程序权限来请求仅限应用程序的令牌(客户端凭据流)以访问 Microsoft Graph。根据您的描述,您在azure门户(azure ad v1.0)中注册了应用程序,您可以尝试以下步骤:

  1. Read mail in all mailboxes为 microsoft graph api设置应用程序权限: 在此处输入图片说明

  2. 请您的管理员通过单击Grant Permissions按钮为当前目录中的所有帐户授予权限(对应用程序权限进行管理员同意),如上图所示。

  3. 使用客户端凭据流通过 ADAL 库获取仅应用程序令牌:AzureAuthenticationProvider .cs:

    public class AzureAuthenticationProvider : IAuthenticationProvider
    {
        private string _azureDomain = "xxxx.onmicrosoft.com";
    
        public async Task AuthenticateRequestAsync(HttpRequestMessage request)
        {
          try
          {
            string clientId = "xxxxx-xxxx-xxxx-xxxx-xxxxxxxx";
            string clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
    
            AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/" + _azureDomain + "/oauth2/token");
    
            ClientCredential credentials = new ClientCredential(clientId, clientSecret);
    
            AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", credentials);
    
            request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
          }
          catch (Exception ex)
          {
          }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果您解码您的令牌,您将Mail.Readrolesclaim 中找到应用程序权限。

  4. 然后你可以使用微软图形客户端库来获取用户的邮件:

        GraphServiceClient graphClient = new GraphServiceClient(new AzureAuthenticationProvider());
    
        //List<ResultsItem> items = new List<ResultsItem>();           
        IMailFolderMessagesCollectionPage messages = await graphClient.Users["77cac441-8279-452e-8904-ff24ddf5c715"].MailFolders.Inbox.Messages.Request().Top(25).GetAsync();
    
    Run Code Online (Sandbox Code Playgroud)
  5. 结果 : 在此处输入图片说明