サード パーティの OAuth IdP 認証を構成する

注:

モバイル クライアントのタブで認証を機能させるには、Microsoft Teams JavaScript クライアント ライブラリ (TeamsJS) のバージョン 1.4.1 以降を使用していることを確認します。

Microsoft Teams アプリは、Facebook、Twitter、Teams など、さまざまなサービスとやり取りする必要がある場合があります。 これらのサービスのほとんどは、アクセスに認証と承認を必要とします。 Teams は、Microsoft Graph を使用してユーザー プロファイル情報Microsoft Entra ID に格納します。 この記事では主に、認証にMicrosoft Entra ID を使用してこの情報にアクセスすることに重点を置いています。

認証のオープン標準である OAuth 2.0 は、Microsoft Entra ID やその他の多数のサービス プロバイダーによって利用されています。 Teams と Microsoft Entra ID で認証を処理する場合は、OAuth 2.0 の理解が不可欠です。 提供される例では、OAuth 2.0 暗黙的な許可フローを使用します。これにより、ユーザーのプロファイル情報がMicrosoft Entra ID と Microsoft Graph から取得されます。

この記事のコードは、Teams サンプル アプリ Microsoft Teams 認証サンプル (ノード) からのものです。 これには、Microsoft Graph のアクセス トークンを要求し、現在のユーザーの基本的なプロファイル情報を Microsoft Entra ID から表示する静的タブが含まれています。

タブの認証フローの概要については、「タブ 内の認証フロー」を参照してください。

タブの認証フローは、ボットの認証フローとは異なります。

注:

このトピックでは、Microsoft Teams JavaScript クライアント ライブラリ (TeamsJS) のバージョン 2.0.x を反映しています。 以前のバージョンを使用している場合は、 最新の TeamsJS と以前のバージョンの違いに関するガイダンスについては、TeamsJS ライブラリの概要を参照してください。

ID プロバイダーとして Microsoft Entra ID を使用するようにアプリを構成する

OAuth 2.0 サポート ID プロバイダーは、登録されていないアプリケーションからの要求を認証しません。 そのため、事前にアプリケーションを登録することが重要です。 Microsoft Entra ID でアプリケーションを登録するには、次の手順に従います。

  1. アプリケーション登録ポータルを開きます。

  2. アプリを選択してそのプロパティを表示するか、[新しい登録] ボタンを選択します。 アプリの [リダイレクト URI ] セクションを見つけます。

  3. ドロップダウン メニューから [ Web ] を選択し、認証エンドポイントへの URL を更新します。 GitHub で使用できる TypeScript/Node.js および C# サンプル アプリでは、リダイレクト URL も同様のパターンに従います。

    リダイレクト URL: https://<hostname>/bot-auth/simple-start

を実際のホストに置き換えます <hostname> 。 このホストには、Azure、Glitch などの専用ホスティング サイト、または開発マシン上の localhost への ngrok トンネル (など abcd1234.ngrok.io) を指定できます。 この情報がない場合は、アプリ (またはサンプル アプリ) を完了またはホストしていることを確認します。 この情報がある場合は、このプロセスを再開します。

注:

LinkedIn、Google など、任意のサード パーティの OAuth プロバイダーを選択できます。 これらのプロバイダーの認証を有効にするプロセスは、サード パーティの OAuth プロバイダーとして Microsoft Entra ID を使用するのと似ています。 サード パーティの OAuth プロバイダーの使用の詳細については、特定のプロバイダーの Web サイトを参照してください。

認証フローを開始する

注:

試験的なサード パーティ製ストレージのパーティション分割が有効になっている場合、サード パーティの認証は失敗します。 アプリは、値がローカルに格納されないため、認証を繰り返し求めます。

ユーザー アクションによって認証フローをトリガーします。 ブラウザーのポップアップ ブロックをトリガーし、ユーザーを混乱させる可能性が高く、認証ポップアップを自動的に開かないようにします。

構成ページまたはコンテンツ ページにボタンを追加して、必要に応じてユーザーがサインインできるようにします。 これは、タブ 構成 ページまたは 任意のコンテンツ ページで実行できます。

Microsoft Entra ID は、ほとんどの ID プロバイダーと同様に、そのコンテンツを にiframe配置することはできません。 つまり、ID プロバイダーをホストするためにポップアップ ページを追加する必要があります。 次の例では、このページは です /tab-auth/simple-start。 ボタンが authentication.authenticate() 選択されている場合は、TeamsJS ライブラリの関数を使用してこのページを起動します。

import { authentication } from "@microsoft/teams-js";
authentication.authenticate({
    url: window.location.origin + "/tab/simple-start-v2",
    width: 600,
    height: 535})
.then((result) => {
    console.log("Login succeeded: " + result);
    let data = localStorage.getItem(result);
    localStorage.removeItem(result);
    let tokenResult = JSON.parse(data);
    showIdTokenAndClaims(tokenResult.idToken);
    getUserProfile(tokenResult.accessToken);
})
.catch((reason) => {
    console.log("Login failed: " + reason);
    handleAuthError(reason);
});

注意事項

  • 渡す authenticate() URL は、認証フローの開始ページです。 この例では、 です /tab-auth/simple-start。 これは、Microsoft Entra アプリケーション登録ポータルで登録した内容と一致する必要があります。

  • 認証フローは、ドメイン上のページから開始する必要があります。 このドメインは、マニフェストの validDomains セクションにも一覧表示する必要があります。 実行に失敗すると、空のポップアップが表示されます。

  • を使用 authenticate()しないと、サインイン プロセスの最後にポップアップが閉じず、問題が発生する可能性があります。

ポップアップ ページ (/tab-auth/simple-start) が表示されると、次のコードが実行されます。 ページのメインの目標は、ユーザーがサインインできるように ID プロバイダーにリダイレクトすることです。 このリダイレクトは、HTTP 302 を使用してサーバー側で行うことができますが、この場合は への呼び出し window.location.assign()を使用してクライアント側で行われます。 これにより、app.getContext()ヒント情報を取得するためにも使用でき、Microsoft Entra ID に渡すことができます。

app.getContext().then((context) => {
    // Generate random state string and store it, so we can verify it in the callback
    let state = _guid(); // _guid() is a helper function in the sample
    localStorage.setItem("simple.state", state);
    localStorage.removeItem("simple.error");

    // Go to the Azure AD authorization endpoint
    let queryParams = {
        client_id: "{{appId}}",
        response_type: "id_token token",
        response_mode: "fragment",
        scope: "https://graph.microsoft.com/User.Read openid",
        redirect_uri: window.location.origin + "/tab/simple-end",
        nonce: _guid(),
        state: state,
        // The context object is populated by Teams; the loginHint attribute
        // is used as hinting information
        login_hint: context.user.loginHint,
    };

    let authorizeEndpoint = `https://login.microsoftonline.com/${context.user.tenant.id}/oauth2/v2.0/authorize?${toQueryString(queryParams)}`;
    window.location.assign(authorizeEndpoint);
});

ユーザーが承認を完了すると、 でアプリ用に指定したコールバック ページに /tab-auth/simple-endユーザーがリダイレクトされます。

注意事項

  • 認証要求と URL の構築に関するヘルプについては、「 ユーザー コンテキスト情報を取得 する」を参照してください。 たとえば、サインインの値としてlogin_hintユーザーのログイン名Microsoft Entra使用できます。つまり、ユーザーの入力が少なくなる可能性があります。 攻撃者が悪意のあるブラウザーにページを読み込み、必要な情報を提供する可能性があるため、ID の証明としてこのコンテキストを直接使用しないでください。
  • タブ コンテキストはユーザーに関する有用な情報を提供しますが、この情報を使用して、タブ コンテンツ URL の URL パラメーターとして取得するか、Microsoft Teams JavaScript クライアント ライブラリ (TeamsJS) で関数を呼び出 app.getContext() すことによってユーザーを認証しないでください。 悪意のあるアクターが独自のパラメーターを使用してタブ コンテンツ URL を呼び出す可能性があり、Microsoft Teams を偽装する Web ページが iframe にタブ コンテンツ URL を読み込み、独自のデータを関数に getContext() 返す可能性があります。 タブ コンテキストの ID 関連の情報は、単にヒントとして扱い、使用する前に検証する必要があります。
  • パラメーターは state 、コールバック URI を呼び出すサービスが、呼び出したサービスであることを確認するために使用されます。 コールバックのパラメーターが state 呼び出し中に送信したパラメーターと一致しない場合、戻り値の呼び出しは検証されないため、終了する必要があります。
  • アプリの manifest.json ファイルの一覧に ID プロバイダーのドメイン validDomains を含める必要はありません。

コールバック ページ

最後のセクションでは、Microsoft Entra承認サービスを呼び出し、ユーザーとアプリの情報を渡して、Microsoft Entra ID がユーザーに独自のモノリシック承認エクスペリエンスを提供できるようにします。 アプリでは、このエクスペリエンスで何が起こるかを制御できなくなります。 ID が指定したコールバック ページMicrosoft Entra呼び出したときに返される内容は、すべて認識されます。/tab-auth/simple-end

このページでは、ID と 呼び出しauthentication.notifySuccess()authentication.notifyFailure()または によって返される情報に基づいて、成功または失敗Microsoft Entra判断する必要があります。 ログインが成功した場合は、サービス リソースにアクセスできます。

// Split the key-value pairs passed from Azure AD
// getHashParameters is a helper function that parses the arguments sent
// to the callback URL by Azure AD after the authorization call
let hashParams = getHashParameters();
if (hashParams["error"]) {
    // Authentication/authorization failed
    localStorage.setItem("simple.error", JSON.stringify(hashParams));
} else if (hashParams["access_token"]) {
    // Get the stored state parameter and compare with incoming state
    let expectedState = localStorage.getItem("simple.state");
    if (expectedState !== hashParams["state"]) {
        // State does not match, report error
        localStorage.setItem("simple.error", JSON.stringify(hashParams));
        authentication.notifyFailure("StateDoesNotMatch");
    } else {
        // Success -- return token information to the parent page.
        // Use localStorage to avoid passing the token via notifySuccess; instead we send the item key.
        let key = "simple.result";
        localStorage.setItem(key, JSON.stringify({
            idToken: hashParams["id_token"],
            accessToken: hashParams["access_token"],
            tokenType: hashParams["token_type"],
            expiresIn: hashParams["expires_in"]
        }));
        authentication.notifySuccess(key);
    }
} else {
    // Unexpected condition: hash does not contain error or access_token parameter
    localStorage.setItem("simple.error", JSON.stringify(hashParams));
    authentication.notifyFailure("UnexpectedFailure");
}

このコードでは、ヘルパー関数を使用して Microsoft Entra ID から受信したキーと値のwindow.location.hashペアを解析しますgetHashParameters()。 が検出 access_tokenされ、値が認証フローの開始時に指定されたものと state 同じである場合は、 を呼び出 notifySuccess()してタブにアクセス トークンを返します。それ以外の場合は、 で notifyFailure()エラーを報告します。

注意事項

NotifyFailure() には、次の定義済みのエラー理由があります。

  • CancelledByUser ユーザーは、認証フローを完了する前にポップアップ ウィンドウを閉じました。

    注:

    親ウィンドウへの接続が中断され、認証 API 呼び出しがエラーで途中で返されるため、ログイン ページの応答ヘッダーには または same-origin-allow-popups の値Cross-Origin-Opener-PolicyCancelledByUser使用same-originしないことをお勧めします。

  • FailedToOpenWindow ポップアップ ウィンドウを開くことができませんでした。 ブラウザーで Microsoft Teams を実行する場合、これは通常、ポップアップ ブロックによってウィンドウがブロックされたことを意味します。

成功した場合は、ページを更新または再読み込みし、現在認証されているユーザーに関連するコンテンツを表示できます。 認証が失敗すると、エラー メッセージが表示されます。

アプリは、ユーザーが現在のデバイスのタブに戻ったときに再びサインインする必要がないように、独自のセッション Cookie を設定できます。

注:

  • Chrome 80 (2020 年初頭にリリース予定) では、新しい Cookie 値を紹介し、既定で Cookie ポリシーを設定します。 既定のブラウザーの動作を利用するのではなく、Cookie に対して使用する目的を設定することをお勧めします。 SameSite cookie 属性 (2020 update)を参照してください
  • Microsoft Teams Free およびゲスト ユーザーに適切なトークンを取得するには、アプリがテナント固有のエンドポイント を利用していることを確認します https://login.microsoftonline.com/**{tenantId}**。 tenantId は、ボット メッセージまたはタブ コンテキストから取得できます。 アプリで を使用 https://login.microsoftonline.com/commonしている場合、ユーザーが正しくないトークンを受け取り、現在サインインしているテナントではなく "ホーム" テナントにログインする可能性があります。

シングル サインオン (SSO) の詳細については、 サイレント認証に関する記事を参照してください。

コード サンプル

Microsoft Entra ID を使用したタブ認証プロセスを示すサンプル コード:

サンプルの名前 説明 .NET Node.js マニフェスト
タブ SSO このサンプル アプリでは、Teams のタブMicrosoft Entra SSO を示します。 表示 表示
Teams Toolkit
該当なし
タブ、ボット、メッセージ拡張機能 (ME) SSO このサンプルでは、Tab、Bot、ME- search、action、link unfurl の SSO を示します。 表示 表示 表示

関連項目