Azure App Service 認証でのサインインとサインアウトのカスタマイズ

この記事では、組み込みの認証と認可を App Service で使用しているときにユーザーのサインインとサインアウトをカスタマイズする方法について説明します。

複数のサインイン プロバイダーを使用する

ポータル構成では、ユーザーに複数 (Facebook と Twitter の両方など) のサインイン プロバイダーを表示するターンキー手法は提供されません。 ただし、この機能をアプリに追加することは難しくありません。 手順の概要は次のとおりです。

最初に、Azure Portal の [認証/承認] ページで、有効にする各 ID プロバイダーを構成します。

[要求が認証されない場合に実行するアクション] で、 [匿名要求を許可する (操作不要)] を選択します。

サインイン ページ、ナビゲーション バー、またはアプリのその他の任意の場所で、有効にした各プロバイダーへのサインイン リンク (/.auth/login/<provider>) を追加します。 次に例を示します。

<a href="/.auth/login/aad">Log in with the Microsoft Identity Platform</a>
<a href="/.auth/login/facebook">Log in with Facebook</a>
<a href="/.auth/login/google">Log in with Google</a>
<a href="/.auth/login/twitter">Log in with Twitter</a>
<a href="/.auth/login/apple">Log in with Apple</a>

ユーザーがいずれかのリンクをクリックすると、それぞれのサインイン ページが開き、ユーザーがサインインできます。

サインイン後のユーザーをカスタム URL にリダイレクトさせるには、post_login_redirect_uri クエリ文字列パラメーターを使用します (ご利用の ID プロバイダーの構成におけるリダイレクト URI と混同しないでください)。 たとえば、サインイン後にユーザーを /Home/Index にリダイレクトさせるには、次の HTML コードを使用します。

<a href="/.auth/login/<provider>?post_login_redirect_uri=/Home/Index">Log in</a>

クライアント主導型サインイン

クライアント主導型サインインでは、アプリケーションでは、プロバイダー固有の SDK を使用して ID プロバイダーにユーザーがサインインします。 その後、結果的に生成された認証トークンが HTTP POST 要求を利用してアプリケーション コードによって App Service に検証のために送信されます (「認証フロー」参照)。 この検証自体では、必要なアプリ リソースへのアクセス権が実際には付与されませんが、検証に成功すると、アプリ リソースへのアクセスに使用できるセッション トークンが付与されます。

プロバイダーのトークンを検証するには、最初に目的のプロバイダーを使用して App Service のアプリが構成されている必要があります。 実行時に、プロバイダーから認証トークンを取得した後、検証のためにトークンを /.auth/login/<provider> にポストします。 次に例を示します。

POST https://<appname>.azurewebsites.net/.auth/login/aad HTTP/1.1
Content-Type: application/json

{"id_token":"<token>","access_token":"<token>"}

トークンの形式は、プロバイダーによって若干異なります。 詳しくは、以下の表をご覧ください。

プロバイダーの値 要求本文に必要 説明
aad {"access_token":"<access_token>"} id_tokenrefresh_tokenexpires_in プロパティは省略可能です。
microsoftaccount {"access_token":"<access_token>"} または {"authentication_token": "<token>" authentication_tokenaccess_token よりも優先されます。 expires_in プロパティは省略可能です。
ライブ サービスからトークンを要求する場合は、常に wl.basic スコープを要求します。
google {"id_token":"<id_token>"} authorization_code プロパティは省略可能です。 authorization_code 値を指定すると、アクセス トークンと更新トークンがトークン ストアに追加されます。 指定した場合、authorization_code には必要に応じて redirect_uri プロパティを指定することもできます。
facebook {"access_token":"<user_access_token>"} Facebook からの有効なユーザー アクセス トークンを使用します。
twitter {"access_token":"<access_token>", "access_token_secret":"<access_token_secret>"}

Note

App Service 認証の GitHub プロバイダーは、カスタマイズされたサインインとサインアウトをサポートしていません。

プロバイダー トークンが正常に検証された場合、API は、セッション トークンである authenticationToken を応答本文に入れて戻ります。

{
    "authenticationToken": "...",
    "user": {
        "userId": "sid:..."
    }
}

このセッション トークンを入手したら、X-ZUMO-AUTH ヘッダーを HTTP 要求に追加することで、保護対象のアプリ リソースにアクセスすることができます。 次に例を示します。

GET https://<appname>.azurewebsites.net/api/products/1
X-ZUMO-AUTH: <authenticationToken_value>

セッションからサインアウトする

ユーザーは、アプリの /.auth/logout エンドポイントに GET 要求を送信することでサインアウトを開始できます。 GET 要求は次の処理を行います。

  • 現在のセッションから認証 Cookie をクリアします。
  • トークン ストアから現在のユーザーのトークンを削除します。
  • Microsoft Entra ID と Google の場合、ID プロバイダーでサーバー側のサインアウトを実行します。

Web ページの簡単なサインアウト リンクを次に示します。

<a href="/.auth/logout">Sign out</a>

既定では、サインアウトに成功すると、クライアントは URL /.auth/logout/complete にリダイレクトされます。 post_logout_redirect_uri クエリ パラメーターを追加して、サインアウト後のリダイレクト ページを変更できます。 次に例を示します。

GET /.auth/logout?post_logout_redirect_uri=/index.html

post_logout_redirect_uri の値をエンコードすることをお勧めします。

完全修飾 URL を使用している場合、URL は同じドメインでホストされているか、アプリの許可された外部リダイレクト URL として構成されている必要があります。 次の例では、同じドメインにホストされていない https://myexternalurl.com にリダイレクトします。

GET /.auth/logout?post_logout_redirect_uri=https%3A%2F%2Fmyexternalurl.com

Azure Cloud Shell で次のコマンドを実行します。

az webapp auth update --name <app_name> --resource-group <group_name> --allowed-external-redirect-urls "https://myexternalurl.com"

URL フラグメントを保持する

ユーザーは、アプリにサインインすると、通常は /wiki/Main_Page#SectionZ のように同じページの同じセクションにリダイレクトされたいと考えます。 ただし、URL フラグメント (たとえば #SectionZ) はサーバーに送信されないため、OAuth のサインインが完了してアプリにリダイレクトされた後は既定で保持されません。 目的のアンカーに再度移動する必要がある場合、ユーザー エクスペリエンスは最適ではありません。 この制限は、すべてのサーバー側認証ソリューションに適用されます。

App Service 認証では、OAuth サインイン全体で URL フラグメントを保存できます。 これを行うには、WEBSITE_AUTH_PRESERVE_URL_FRAGMENT というアプリ設定を true に設定します。 Azure portal で行うか、Azure Cloud Shell で次のコマンドを実行するだけです。

az webapp config appsettings set --name <app_name> --resource-group <group_name> --settings WEBSITE_AUTH_PRESERVE_URL_FRAGMENT="true"

サインイン アカウントのドメインの制限

Microsoft アカウントと Microsoft Entra ID の両方に複数のドメインからサインインできます。 たとえば、Microsoft アカウントでは outlook.comlive.comhotmail.com アカウントが許可されます。 Microsoft Entra ID では、サインイン アカウントに任意の数のカスタム ドメインが許可されます。 ただし、ユーザーを独自のブランドの Microsoft Entra サインインページ (contoso.comなど) に直接誘導することもできます。 サインイン アカウントのドメイン名を提示するには、以下の手順に従います。

  1. https://resources.azure.com で、ページの上部にある [読み取り/書き込み] を選択します。

  2. 左側のブラウザーで、subscriptions><subscription-name>resourceGroups><resource-group-name>>providers>Microsoft.Web>sites><app-name>>config>authsettingsV2 に移動します。

  3. [編集] をクリックします。

  4. domain_hint 項目を含む loginParameters 配列を追加します。

    "identityProviders": {
        "azureActiveDirectory": {
            "login": {
                "loginParameters": ["domain_hint=<domain-name>"],
            }
        }
    }
    
  5. [Put] をクリックします。

この設定で、domain_hint クエリ文字列パラメーターがログイン リダイレクト URL に追加されます。

重要

クライアントは、リダイレクト URL を受け取った後で domain_hint パラメーターを削除し、別のドメインでログインできます。 そのため、この機能は便利ですが、セキュリティ機能ではありません。

ユーザーを承認または拒否する

App Service は最も単純な承認ケース (つまり、認証されていない要求の拒否) を処理しますが、アプリでは、特定のユーザー グループだけにアクセスを制限するなど、よりきめ細かな承認動作が必要になる場合があります。 場合によっては、サインインしたユーザーに対してアクセスを許可または拒否するためのカスタム アプリケーション コードの記述が必要になります。 また、App Service やお使いの ID プロバイダーが、コードの変更を必要とせずにサポートできる場合もあります。

サーバー レベル (Windows アプリのみ)

Windows アプリでは、Web.config ファイルを編集して IIS Web サーバーの承認動作を定義できます。 Linux アプリは、IIS を使用しないため、Web.config を使用して構成することはできません。

  1. https://<app-name>.scm.azurewebsites.net/DebugConsole に移動します

  2. App Service ファイルのブラウザー エクスプローラーで、site/wwwroot に移動します。 Web.config が存在しない場合は、+>[新しいファイル] を選択して作成します。

  3. Web.config の鉛筆を選択して編集します。 次の構成コードを追加し、 [保存] をクリックします。 Web.config が既に存在する場合は、すべての内容を含めた <authorization> 要素を追加するだけです。 許可するアカウントを <allow> 要素に追加します。

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
       <system.web>
          <authorization>
            <allow users="user1@contoso.com,user2@contoso.com"/>
            <deny users="*"/>
          </authorization>
       </system.web>
    </configuration>
    

ID プロバイダー レベル

ID プロバイダーによって特定のターンキー承認が提供される場合があります。 次に例を示します。

アプリケーション レベル

他のいずれのレベルでも必要な承認が提供されない場合、またはお使いのプラットフォームまたは ID プロバイダーがサポートされていない場合、ユーザーの要求に基づいてユーザーを承認するカスタム コードを記述する必要があります。

その他のリソース