顯示使用者的電子郵件

已完成

您執行了 ASP.NET Core 應用程式並將其連線至 Microsoft 365。 現在是擷取使用者的電子郵件,並將它們顯示在您的應用程式中的時候。

決定您的應用程式需要的權限

Microsoft Graph 公開的所有資料都受到保護,而且您的應用程式必須獲與適當權限才能存取它。 需要的權限取決於您的應用程式需要存取的資訊類型。 例如,若要存取使用者的電子郵件訊息,您的應用程式必須擁有 Mail.Read 權限。 Microsoft Graph API 參考中提供每項作業所需權限的確切清單。

如果您的應用程式載入不同類型的資料,使用者將必須授與其存取此資訊所需的多個權限。 建議您僅在應用程式中要求您需要的權限。

指定必要權限

授與您應用程式的權限清單會一併放入存取權杖中。 OAuth 標準將其稱為「範圍」。 當您的應用程式使用 MSAL 來取得存取權杖,它需要在對 Azure Active Directory 的要求中包含範圍清單。 Microsoft Graph 中的每個作業都有自己的範圍清單。 如果您的存取權杖沒有其中一個權杖,則要求會遭到拒絕。

如您稍早所見,範例應用程式會將必要的權限儲存在 appsettings.json 檔案的 Scopes 屬性中。

"Scopes": "user.read presence.read mailboxsettings.read mail.read"

Scopes 屬性值是由應用程式的 ASP.NET Core 中介軟體所使用,其會處理使用者成功登入後存取權杖的擷取。

中介軟體:Microsoft 身分識別平台和 Microsoft Graph

ASP.NET Core 支援可用來驗證和授權使用者的中介軟體。 它也可以用來擷取可呼叫 Microsoft Graph 的權杖、將名為 GraphServiceClient 的 Microsoft Graph SDK 物件插入應用程式、建立權杖快取等等。 中介軟體是在 Startup.cs 中設定,並處理下列工作。

  1. appsettings.json 擷取 Scopes 屬性中定義的必要權限。
  2. 新增 OpenId 驗證的支援。
  3. 指定應用程式是需要驗證碼流程的 Microsoft 身分識別平台 Web 應用程式。
  4. 新增使用特定權限呼叫 Microsoft Graph API 的能力。
  5. 啟用 GraphServiceClient 的相依性插入 (Microsoft Graph SDK 提供的物件,用來進行 Microsoft Graph 呼叫)。
  6. 新增記憶體內部權杖快取。
  7. 需要已驗證的使用者存取應用程式。
  8. 啟用 Razor Pages 支援。
  9. 新增提供使用者登入和登出支援的 Microsoft 身分識別 UI 頁面。

您可以在下列程式碼中查看每個步驟,其會在 Startup.csConfigureServices() 方法中定義。

// 1. Retrieve required permissions from appsettings
string[] initialScopes =
Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');

services
  // 2. Add support for OpenId authentication
  .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)

  // 3. Microsoft identity platform web app that requires an auth code flow
  .AddMicrosoftIdentityWebApp(Configuration)

  // 4. Add ability to call Microsoft Graph APIs with specific permissions
  .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)

  // 5. Enable dependency injection for GraphServiceClient
  .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))

  // 6. Add in-memory token cache
  .AddInMemoryTokenCaches();

// 7. Require an authenticated user
services.AddControllersWithViews(options =>
{
  var policy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();
  options.Filters.Add(new AuthorizeFilter(policy));
});

services
  // 8. Add Razor Pages support
  .AddRazorPages()

  // 9. Add Microsoft Identity UI pages that provide user
  // sign-in and sign-out support
  .AddMicrosoftIdentityUI();

設定必要的中介軟體後,應用程式將自動處理使用者的登入,並擷取存取權杖。 然後可以使用存取權杖來擷取使用者的電子郵件訊息,因為它將包含必要的權限。 讓我們看看該程序如何運作。

從 Microsoft Graph 中擷取使用者的電子郵件

若要從 Microsoft Graph 取得使用者的電子郵件,您需要呼叫 /me/messages 端點。 它會傳回已登入使用者信箱中的電子郵件清單。 您可以使用先前在中介軟體區段提到的 GraphServiceClient 物件呼叫 Microsoft Graph。 無需手動呼叫 HTTP,GraphServiceClient 即可提供可用於呼叫 Microsoft Graph 的 API。

以下是使用 GraphServiceClient 呼叫擷取使用者電子郵件訊息的範例:

var emails = await _graphServiceClient.Me.Messages
            .Request()
            .GetAsync();

Microsoft Graph 端點會以任意順序傳回資料。 若要確保您取得最新的訊息,請依收到訊息的日期進行遞減排序:

var emails = await _graphServiceClient.Me.Messages
            .Request()
            .OrderBy("receivedDateTime desc")
            .GetAsync();

從 Microsoft Graph 中擷取資料時,您應一律僅擷取您需要的資料。 將 Microsoft Graph 需要透過網路擷取和傳輸至應用程式資料量最小化,將有助於大幅改善您應用程式的效能。

您可以用兩種方式限制從 Microsoft 365 中擷取的資料量:

  • 選取您想要取得的項目數。
  • 選取應包含的特定資訊。

若要指定您要擷取的屬性,請使用 Select 方法延伸 Microsoft Graph 要求,並建立定義要傳回屬性的物件。 例如,若要取得僅包含其主旨和接收日期/時間的電子郵件清單,請使用以代碼:

var emails = await _graphServiceClient.Me.Messages
            .Request()
            .Select(msg => new {
              msg.Subject,
              msg.ReceivedDateTime
            })
            .OrderBy("receivedDateTime desc")
            .GetAsync();

您可以在 Microsoft Graph API 參考中找到每個端點上可用屬性的完整清單。

您可以執行以限制從 Microsoft 365 傳回的資料量的另一個動作,就是指定您想要擷取多少個項目。 若要這樣做,請使用 Top 方法延伸 Microsoft Graph 要求。 例如,若要擷取最近收到的 10 封電子郵件,可以使用以下代碼:

var emails = await _graphServiceClient.Me.Messages
            .Request()
            .Select(msg => new {
              msg.Subject,
              msg.ReceivedDateTime
            })
            .OrderBy("receivedDateTime desc")
            .Top(10)
            .GetAsync();

讓我們檢查一下如何在應用程式中使用此代碼。