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

时间:2017-06-08 18:58:26

标签: c# asp.net-mvc azure azure-active-directory microsoft-graph

我似乎在向我的应用程序提供访问oranization的电子邮件中访问其他用户所需的权限时遇到问题。我让我的管理员通过Azure门户授予我的应用程序所有可能的权限,并且我从Graph网站下载的测试应用程序中收到“Access is Denied”错误。这让我觉得我可能没有使用正确的API调用。

以下是我用来检索其他用户电子邮件的代码:

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

其中“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 });
        }
    }

(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;
    }

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

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

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

  1. 为microsoft graph api设置Read mail in all mailboxes个应用程序权限: enter image description here

  2. 点击Grant Permissions按钮,让管理员为当前目录中的所有帐户授予权限(对管理员同意以获得应用程序权限)。

  3. 使用客户端凭据流使用ADAL库获取仅限app的令牌: 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)
          {
          }
        }
    }
    

    如果您解码了令牌,您会在Mail.Read声明中找到roles app权限。

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

        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();
    
  5. 结果: enter image description here