В прошлый раз мы обсудили механизм авторизации для работы с Office 365 API (в частности с Microsoft Graph API):

  • при каждом вызове API нужно передать token. Token имеет ограниченный срок жизни
  • token выдает сервис Microsoft, так называемый “Azure AD Authorization Endpoint”
  • получить token можно без серверной части используя только JavaScript в браузере. Для этого Microsoft сделал JavaScript библиотеку ADAL JS, которая упрощает коммуникацию с “Azure AD Authorization Endpoint” для получения token.

Тогда мы сделали простую статичную HTML-страницу, на которой наш vanilla JavaScript делал запрос к Microsoft Graph API и отображал список писем из Office 365. В данной заметке разовьем пример и сделаем тоже самое на Angular5.

angular5 office 365 adal js

Также поговорим о различиях рабочих (Work or school account) и персональных (Personal Account) аккаунтов при использовании Office 365 API.

Пример на GitHub.

Будем считать, что вы знакомы с предыдущей статьёй, понимаете процесс получения и использования token, уже зарегистрировали приложение в Azure, получили Application ID.

ADAL JS и MSAL JS


У Microsoft есть два вида аккаунтов:
— Work or school Account
— Personal Account

Work or school account создается (и удаляется) администратором компании, которая купила подписку Office 365. Сотрудники используют его, например, для подключения к корпоративной почте, SharePoint, OneDrive.

Personal Account создаете вы сами, используется для подключения к персональным сервисам, например личному OneDrive.
Более подробно про Work и Personal аккаунты можно почитать тут “Understanding Microsoft Work And Personal Accounts”.
Office 365 API (например Microsoft Graph API) имеет разную поддержку для персональных и рабочих аккаунтов. Например, работать с почтой могут и Work account и Personal account, но не существует персонального SharePoint (а следовательно, и API SharePoint для Personal account).

Мы уже знаем, что token для вызовов API выдает “Azure AD Authorization Endpoint”. Точек авторизации существует 2:

  • Authorization Endpoint
    Выдает токены только для Work Account-ов.
    При логине пользователь отправляется на
    https: //login.microsoftonline.com/common/oauth2/authorize?client_id=...
  • Authorization Endpoint v2.0
    Выдает токены как для Work так и для Personal Account-ов
    При логине пользователь отправляется на
    https: //login.microsoftonline.com/common/oauth2/v2.0/authorize?
    client_id=…

Зачем тогда вообще нужен “Authorization Endpoint”? Особенность заключается в том, что “Authorization Endpoint v2.0” выдаст токен только для тех возможностей API которые есть и для Work и для Personal аккаунтов. Т.е. используя Endpoint v2.0 и Work account вы сможете получить доступ к почте, но не будет доступа к API SharePoint (подробнее о том какие API поддерживает Endpoint v2.0 см в ссылках в конце).

В настоящее время v2.0 endpoint не работает с приложениями, которые зарегистрированы в корпоративном Azure портале (такую регистрацию мы делали в прошлой заметке), нужно использовать отдельный Microsoft Application Registration Portal.

Microsoft обещает в будущем расширить возможности v2.0 endpoint, и обеспечить поддержку приложений, зарегистрированных в корпоративном Azure портале — v2.0 endpoint сможет выдать для них токены. А пока, для корпоративных приложений, Microsoft рекомендует использовать “Authorization Endpoint”:
If your application only needs to support Microsoft work and school accounts, don't use the v2.0 endpoint
ADAL JS работает с “Authorization Endpoint”, MSAL JS с v2.0 endpoint. В данной заметке мы будем использовать Authorization Endpoint первой версии и соответственно ADAL JS.

Angular 5 и ADAL JS


Нам понадобится установленный Node.js, npm, и Angular CLI – утилита которая помогает создавать и собирать Angular проекты. Весь процесс хорошо описан в Angular QuickStart.

Сделаем новый проект:

ng new angular5-office365-adal-example

Не существует официальных (от Microsoft) TypeScript d.ts описаний для Adal.js. Несколько вариантов использования Adal.js в Angular 5:

  1. Не использовать d.ts описания, объявить объект AuthenticationContext (из Adal.js) как глобальный any и писать нетипизированный код как на обычном JavaScript
  2. Самому сделать d.ts описание
  3. Воспользоваться проектом adal-angular5, который является калькой оригинального adal-angular.js для AngularJS от Microsoft (Adal js)
  4. Есть проекты, в которых Adal js полностью переписан на TypeScript (adal-ts, adal-typescript)
  5. Воспользоваться готовым d.ts описанием.

5 вариант выглядит самым простым и удобным: используется оригинальный Adal.js от Microsoft и с помощью d.ts описания добавляете intellisense и проверки при сборке.

Установим проверенные d.ts описания для Adal.js. Находясь в папке проекта:

npm install --save @types/adal

У нас пример тестовый, поэтому сделаем его максимально простым: будем подключаться к Microsoft Graph API прямо в AppComponent.

В файле app.component.ts импортируем HttpClient и adal

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { } from 'adal'; // без этого приложение будет собираться, но будут сообщения об ошибках

В app.module.ts подключим HttpClientModule

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http'; //<- ADD

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule //<- ADD
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Подключим js-библиотеку к странице

adal js link

Дальше будет точно такой же код как в прошлом примере на JS.

В ngOnInit проверим авторизован пользователь или нет, если не авторизован или token протух отправим пользователя на страницу регистрации.

let config: adal.Config = {
  tenant: 'igtit.onmicrosoft.com',
  clientId: '21XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
  postLogoutRedirectUri: window.location.origin,
  endpoints: {
    graphApiUri: "https://graph.microsoft.com",
  },
  cacheLocation: "localStorage",
  redirectUri: ''
};

let authContext = new AuthenticationContext(config);

let isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();

if (isCallback && !authContext.getLoginError()) {
  window.location.href = (<any>authContext)._getItem((<any>authContext).CONSTANTS.STORAGE.LOGIN_REQUEST);
}

// check if user need to login
let user = authContext.getCachedUser();
let token = authContext.getCachedToken(config.clientId);
if (!user || !token) {
  authContext.login();
}

Теперь можно использовать token для вызова Microsoft Graph API

authContext.acquireToken(config.endpoints.graphApiUri, (error, token) => {

  // call Microsoft Graph API with token

  let url = config.endpoints.graphApiUri + "/v1.0/me/messages";
  this.http.get(url, {
    headers: {
      "Authorization": "Bearer " + token
    }
  }).subscribe(mgs => this.messages = (<any>mgs).value);

});

Полный пример на GitHub.

Ссылки


Active Directory Authentication Library (ADAL) for JavaScript
Microsoft Authentication Library Preview for JavaScript (MSAL.js)
Should I use the v2.0 endpoint?
What's different about the v2.0 endpoint?
Understanding Microsoft Work And Personal Accounts

Комментарии (2)


  1. slayeek
    02.02.2018 19:52

    Познавательно, спасибо. Но переименуйте все же GitHab в GitHub :).


  1. vintage
    03.02.2018 14:17

    import { } from 'adal'; // без этого приложение будет собираться, но будут сообщения об ошибках

    Подозреваю должно быть так:


    import 'adal'; // без этого приложение будет собираться, но будут сообщения об ошибках