Доступ к событиям календаря пользователя с помощью Microsoft Graph

Завершено

Вы запустили приложение ASP.NET Core и подключили его к Microsoft 365. В этом уроке вы узнаете, как отображать события календаря пользователя на предстоящую неделю. Вы также узнаете, как запрашивать события данных за указанный период. Наконец, вы изучите такие понятия, как выбор и порядок отображения сведений нужным образом.

Выбор разрешений, необходимых вашему приложению

Все данные, предоставляемые из Microsoft Graph, защищены, и вашему приложению должны быть предоставлены соответствующие разрешения на доступ к ним. Необходимые разрешения зависят от типа сведений, к которым приложение должно получить доступ. Например, для доступа к календарю пользователя у вашего приложения должно быть разрешение Calendars.Read. Точный список разрешений, необходимых для каждой операции, доступен в справочнике по API Microsoft Graph.

Если приложение загружает данные различных типов, пользователи должны предоставить ему несколько разрешений, необходимых для доступа к этим сведениям. Рекомендуется запрашивать в приложении только необходимые разрешения.

Указание необходимых разрешений

Список разрешений, предоставленных вашему приложению, включается прямо в маркер доступа. В стандарте OAuth они называются "областями". Когда приложение использует библиотеку MSAL для получения маркера доступа, оно должно включить список областей в запрос к Azure Active Directory. У каждой операции в Microsoft Graph есть собственный список областей. Если у маркера доступа нет одной из них, запрос отклоняется.

В примере приложения необходимые разрешения сохраняются в файле appsettings.json в свойстве Scopes, как было показано ранее.

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

Значение свойства Scopes используется в ПО промежуточного слоя ASP.NET Core приложения, где обрабатывается получение маркера доступа после успешного входа пользователя.

ПО промежуточного слоя: платформа удостоверений Майкрософт и Microsoft Graph

ASP.NET Core поддерживает ПО промежуточного слоя, которое можно использовать для проверки подлинности и авторизации пользователей. Оно также может использоваться для получения маркера, применимого для вызова Microsoft Graph, вставки в приложение объекта пакета SDK Microsoft Graph с именем GraphServiceClient, создания кэша маркеров и для других целей. ПО промежуточного слоя настроено в Startup.cs и выполняет указанные ниже задачи.

  1. Извлечение из appsettings.json необходимых разрешений, определенных в свойстве Scopes.
  2. Добавление поддержки проверки подлинности OpenId.
  3. Указание, что приложение является веб-приложением платформы удостоверений Майкрософт, требующим потока кода проверки подлинности.
  4. Добавление возможности вызывать API Microsoft Graph с определенными разрешениями.
  5. Включение внедрения зависимостей для GraphServiceClient (объект из пакета SDK Майкрософт Graph, используемый для вызовов Microsoft Graph).
  6. Добавление кэша маркеров в памяти.
  7. Требование проверки подлинности пользователя для доступа к приложению.
  8. Включение поддержки Razor Pages.
  9. Добавление страниц пользовательского интерфейса платформы удостоверений Майкрософт, которые обеспечивают поддержку входа и выхода пользователя.

Каждое из этих действий можно увидеть в следующем коде, определенном в методе ConfigureServices() файлаStartup.cs.

// 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, необходимо вызвать конечную точку /me/calendarview . Она возвращает список событий календаря из стандартного календаря вошедшего пользователя. Microsoft Graph можно вызвать с помощью объекта GraphServiceClient, который был упомянут ранее в разделе ПО промежуточного слоя. GraphServiceClient предоставляет API, которые можно использовать для вызова Microsoft Graph: это избавляет от необходимости делать HTTP-вызовы вручную. Чтобы показать события календаря на предстоящей неделе, необходимо определить даты начала недели и конца недели.

// Configure a calendar view for the current week
var startOfWeek = DateTime.Now;
var endOfWeek = startOfWeek.AddDays(7);

Затем эти даты добавляются в список QueryOption, определяющий диапазон выбранных событий.

var viewOptions = new List<QueryOption>
{
  new QueryOption("startDateTime", startOfWeek.ToString("o")),
  new QueryOption("endDateTime", endOfWeek.ToString("o"))
};

После этого объект GraphServiceClient (внедренный в конструктор класса модели страницы Razor) используется для вызова Me.CalendarView, и список viewOptions передается в метод Request для ограничения объема результатов. Код также включает предпочтительный часовой пояс пользователя, определяемый вызовом метода Header.

// Use the injected GraphServiceClient object to call into Me.CalendarView
var calendarEvents = await _graphServiceClient
    .Me
    .CalendarView
    .Request(viewOptions)
    .Header("Prefer", $"outlook.timezone=\"{userTimeZone}\"")

Сведение к минимуму объему данных, которые получает и передает Microsoft Graph, значительно повышает производительность вашего приложения. Метод GraphServiceClient’s можно использовать для выбора определенных свойств, которые будет использовать приложение.

.Select(evt => new
{
    evt.Subject,
    evt.Organizer,
    evt.Start,
    evt.End
})

Наконец, метод OrderBy используется для указания порядка сортировки результатов, а GetAsync вызывается для запуска запроса.

.OrderBy("start/DateTime")
.GetAsync();

В данном случае код будет сортировать результаты по дочернему свойству DateTime свойства start. Чтобы сортировать результаты по нескольким полям, укажите список полей через запятую. Также можно указать, в каком порядке нужно сортировать элементы (по возрастанию или по убыванию), добавив в запрос ключевое слово asc или desc. Полная версия кода показана далее:

// Configure a calendar view for the current week
var startOfWeek = DateTime.Now;
var endOfWeek = startOfWeek.AddDays(7);

var viewOptions = new List<QueryOption>
{
    new QueryOption("startDateTime", startOfWeek.ToString("o")),
    new QueryOption("endDateTime", endOfWeek.ToString("o"))
};

// Use the injected GraphServiceClient object to call into Me.CalendarView
var calendarEvents = await _graphServiceClient
    .Me
    .CalendarView
    .Request(viewOptions)
    .Header("Prefer", $"outlook.timezone=\"{userTimeZone}\"")
    .Select(evt => new
    {
        evt.Subject,
        evt.Organizer,
        evt.Start,
        evt.End
    })
    .OrderBy("start/DateTime")
    .GetAsync();

Рассмотрим, как использовать этот код в приложении.