> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

# アプリケーションの実装（Webアプリ + SSO）

> 通常のWebアプリシナリオでのアプリケーションの実装

通常のWebアプリケーションの実装について説明します。実装にはASP .NET Coreを使用しました。コードは[こちらのGitHubリポジトリ](https://github.com/auth0-samples/auth0-pnp-webapp-oidc)にあります。

サンプルには、会社の従業員の認証にActive Directory統合を使用し、社外の請負業者用にAuth0データベース接続を使用するアプリケーションが含まれています。認可は、ルールとクレームを使用して実装されており、この段落で詳しく説明します。

## ユーザーログイン

Auth0には、アプリケーションのログインコンポーネントとして機能するLockウィジェットがあるため、独自のログイン画面を実装する必要がありません。Lockウィジェットは、データベース接続であれ、ソーシャル接続であれ、エンタープライズ接続であれ、<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=auth0-dashboard" tip="Auth0 Dashboard: サービスを構成するためのAuth0の主製品。" cta="用語集の表示">Auth0 Dashboard</Tooltip>内で構成したすべての接続とシームレスに統合します。

WebアプリケーションとAuth0を使用してログイン画面を実装する方法には、いくつかの異なる方法があります。

* **ホストされたLock** ：Auth0のインフラストラクチャでホストされているLockウィジェットのインスタンスを使用します。
* **埋め込まれたLock** ：アプリケーションのWebページ内にLockウィジェットを埋め込みます。実際のLockウィジェットにはいくつかのカスタマイズオプションがあり、ページ上の他のHTMLを完全に制御できます。
* **カスタムUI** ：ログイン画面用に完全カスタムのWebページを開発します。カスタムHTMLフォームがお使いのサーバーにポストバックされると、サーバーはAuthentication APIを使用してユーザーを認証します。カスタムUIを使用するタイミングについての詳細は、「[LockまたはSDKを使用してクラシックログインページをカスタマイズする](/docs/ja-jp/customize/login-pages/classic-login/customize-with-lock-sdk)」を参照してください。

推奨されるベストプラクティスは、ホストされたLockを使用することです。最も安全で、ユーザーがアプリケーションにログインできるようになる最も簡単な方法だからです。

### ホーム領域検出（HRD）を自動化する

Lockではデフォルトで、ログイン可能なすべての接続が表示されます。複数のオプションから適切なIDプロバイダーを選択することを、「ホーム領域検出（HRD）」と呼びます。今回の事例では、オプションはActive Directory（会社の従業員向け）で認証するか、データベース接続（社外の請負業者向け）にメール/パスワードを使用するかのいずれかとなります。

しかし、ユーザーがIDプロバイダー（<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-2" href="/docs/ja-jp/glossary?term=idp" tip="IDプロバイダー（IdP）: デジタルIDを保存および管理するサービス。" cta="用語集の表示">IdP</Tooltip>）を選択する必要がある最初のステップを省略し、毎回IdPをたずねるのではなく、システムがこれを特定するようにしたい場合があります。Lockには以下のオプションがあります。

* **プログラムによってIdPを特定する** ：Auth0で認証トランザクションを開始する際に、オプションで`connection`パラメーターを送信することができます。この値は、Dashboardで定義されている任意の接続に直接マッピングしています。`/authorize`エンドポイントを呼び出してホストされたLockを使用する場合、接続名を含む`connection`クエリ文字列パラメーターを渡すことができます。あるいは埋め込まれたLockを使用している場合は、`auth0.show({connections:['{yourConnection}']});`と記述するだけなので簡単です。

  * `connection`値を取得するための実用的な方法は複数あります。そのうちの1つは、**バニティURL** を使用する方法です。たとえば、会社の従業員は`https://internal.yoursite.com`を使用し、社外の請負業者は`https://external.yoursite.com`を使用するようにします。
* **メールドメインを使用する** ：Lockでは、メールドメインを認証要求のルーティング方法として使用することができます。Auth0のエンタープライズ接続は`domains`にマッピングすることができます。このセットアップが接続に存在する場合、マッピングされたドメインのメールアドレスを入力すると、パスワードテキストボックスが自動的に無効になります。複数のドメインを1つの接続に関連付けることもできます。

このトピックに関する追加情報は、「[複数の接続オプションから選択する](/docs/ja-jp/libraries/lock/selecting-from-multiple-connection-options)」を参照してください。

## セッション管理

セッション管理について話す場合、通常、考慮すべき3つのレイヤーのセッションがあります。

* **アプリケーションセッション** ：最初のレイヤーはアプリケーションの内部セッションです。アプリケーションがAuth0を使用してユーザーを認証していたとしても、ユーザーがアプリケーションにログインしたという事実を追跡する必要があります。通常のWebアプリケーションでは、これは情報をクッキーに保存することで達成されます。
* **Auth0セッション** ：次に、Auth0もセッションを保持し、ユーザーの情報をクッキー内に保存します。次回、ユーザーがAuth0のLock画面にリダイレクトされた時に、ユーザーの情報は保存されます。
* **IDプロバイダーセッション** ：最後のレイヤーはIDプロバイダー（FacebookやGoogleなど）です。ユーザーがこれらのプロバイダーのいずれかでサインインできるように許可しており、ユーザーがすでにプロバイダーにサインインしている場合、再度サインインを求められることはありません。ユーザーは、Auth0と、そしてひいてはアプリケーションと、情報を共有するための権限を与えるだけで済むかもしれません。

したがって、Webアプリケーションを開発している場合は、ユーザーがWebアプリケーションにログインしたという事実を追跡する必要があります。これは、クッキーベースのセッションを使用してユーザーがサインインした事実を追跡し、ユーザーに関連する情報やトークンを保存することで行うことができます。

<Info>
  ### どのようにユーザーのローカルアプリケーションセッションの期間を制御すればよいですか？Auth0から操作できますか？

  Webアプリは、ユーザーのローカルアプリケーションセッションを完全に制御できます。実行方法は通常、使用されているWebスタックにより異なります（例：ASP.NET）。すべてのアプローチは最終的に1つ以上のクッキーを使用してセッションを制御します。開発者は、Auth0から返されるJWT IDトークンの有効期限を使用してセッションの期間を制御するか、それを完全に無視するかを選択できます。開発者によっては、IDトークン自体をセッション状態に保存し、期限が切れた時にユーザーのセッションを終了することもあります。トークンの有効期限を使用してローカルセッションの有効期限を決定する理由は、それによって、Auth0 Dashboardからユーザーセッションの期間を一元管理できるからです。
</Info>

ログインフローは次のとおりです。

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0/docs/images/ja-jp/cdy7uua7fh8z/4bqozVk6fF4JrWRP1BJK7Y/2bf6d6fb04b1d8c42ea6439e8f611a03/login-flow.png" alt="undefined" />
</Frame>

1. **OIDC認証フローを開始する** ：ユーザーのブラウザーは、OIDCフローを開始するためにAuth0に要求を送信します。
2. **SSOクッキーを設定する** ：Auth0は、ユーザーの情報を保存するためにクッキーを設定します。
3. **コードの交換とIDトークンの返却** ：Auth0はWebサーバーに要求を送り、コードを返します。WebサーバーがIDトークンのコードを交換します。
4. **認証クッキーを設定し、応答を送信する** ：Webサーバーはブラウザーに応答を返し、アプリケーションの認証クッキーを設定してユーザーのセッション情報を保存します。
5. **以降のすべての要求に認証クッキーが送信される** ：アプリケーションの認証クッキーが、ユーザーが認証されている証明として以降のすべての要求に対して送信されます。

<Info>
  ### Auth0のSSOセッションがアプリケーションのセッションに影響を与える方法

  Auth0は、独自のシングルサインオンセッションを管理します。アプリケーションは、独自のローカルセッションを維持する際に、そのSSOセッションを尊重するか無視するかを選択できます。Lockウィジェットには、Auth0のSSOセッションが存在するかを検出し、同じユーザーとして再度ログインしたいかを聞く特殊機能があります。

  <Frame>![LockウィジェットSSO](https://cdn2.auth0.com/docs/1.14567.0/media/articles/architecture-scenarios/web-app-sso/sso-login.png)</Frame>

  再度ログインしたい場合には、実際のIDPで資格情報を再入力することなくサインインすることができます。ユーザーが認証しなくても、アプリケーションはAuth0de認証フローを実行し、新しいローカルアプリケーションセッションの管理に使用できる新しいIDトークンを取得します。
</Info>

[**ASP.NET Core**](/docs/ja-jp/architecture-scenarios/application/web-app-sso/implementation-aspnetcore#configure-the-cookie-and-oidc-middleware)**での実装を参照してください**。

## ユーザーログアウト

ユーザーをログアウトさせる際には、先程話した3つのレイヤーのセッションについて再度考慮する必要があります。

* **アプリケーションセッション** ：ユーザーのセッションを消去して、Webアプリケーションからユーザーをログアウトさせる必要があります。
* **Auth0セッション** ：Auth0からユーザーをログアウトさせる必要があります。これを行うには、ユーザーを`https://{yourDomain}/v2/logout`にリダイレクトします。ユーザーをこのURLにリダイレクトすると、ユーザーについてAuth0が設定したシングルサインオンのクッキーがすべて消去されます。
* **IDプロバイダーセッション** ：一般的な方法ではありませんが、たとえばFacebookやGoogleなど、使用しているIDプロバイダーからユーザーを強制的にログアウトさせることもできます。これを行うには、ログアウトURLに`federated`クエリ文字列パラメーターを追加します：`https://{yourDomain}/v2/logout?federated`。

ログアウト後にユーザーをリダイレクトするには、ターゲットURLを値として、`returnTo`クエリ文字列パラメーターを追加します：`https://{yourDomain}/v2/logout?returnTo=http://www.example.com`。`returnTo` URLを **［Allowed Logout URLs（許可されているログアウトURL）］** に追加する必要があることに留意してください。詳しい実装方法については、「[ログアウト](/docs/ja-jp/authenticate/login/logout)」をご覧ください。

ログアウトフロー（フェデレーションログアウトを除く）は次のとおりです。

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0/docs/images/ja-jp/cdy7uua7fh8z/5t5iXTeGMUzyKHhqOAGRmp/07faefa7e8c19ba033faacc85dd0703d/logout-flow.png" alt="undefined" />
</Frame>

1. **ログアウトフローを開始する**：ログアウトフローは、たとえばユーザーが **［Logout（ログアウト）］** リンクをクリックすることなどによって、ブラウザーから開始されます。Webサーバーに要求が送信されます。
2. **ユーザーのローカルセッションを消去する**：ユーザーのアプリケーションセッション/クッキーが消去されます。
3. **ブラウザーをAuth0のログアウトページにリダイレクトする**：ユーザーのブラウザーはAuth0のログアウトURLにリダイレクトされます。
4. **SSOクッキーを消去する**：Auth0はユーザーのSSOクッキーを消去します。
5. **ログアウト後のURLにリダイレクトする**：Auth0はリダイレクト応答を返し、ユーザーのブラウザーを`returnTo`クエリ文字列パラメーターにリダイレクトします。

[**ASP.NET Core** ](/docs/ja-jp/architecture-scenarios/application/web-app-sso/implementation-aspnetcore#implement-the-logout)**での実装を参照してください** 。

## アクセス制御

認可とは、ユーザーがアプリケーション内で実行できるアクションを決定するプロセスを指します。

Auth0とは独立してアプリケーション内で認可を直接実装するか、使用可能な方法の1つを使用してユーザーの認可レベルを取得し、それをIDトークン内の認可クレームとして設定し、いったんトークンを取得したらアプリケーション内でこれらのクレームを検証してアクセス制御を行うことができます。

Auth0を使用する際には、ユーザー認可クレームを取得および設定するさまざまな方法があります。

* [Auth0認可拡張機能](/docs/ja-jp/customize/extensions/authorization-extension)を構成して使用する。
* Active Directoryのグループを使用する。これらは、Active DirectoryのグループをAuthorization Extension（認可拡張機能）を使用して定義したグループにマッピングすることで、認可拡張機能と組み合わせて使用することができます。
* [ルール](/docs/ja-jp/customize/rules)を利用してユーザープロファイルにメタデータを追加する。
* ルール内から外部サービスを呼び出す。

今回の事例では、すでに会社にActive Directoryが設定されているため、Active Directoryグループと組み合わせて認可拡張機能を使用してアクセス制御を強制します。

<Card title="認可拡張機能">
  認可拡張機能は、現時点では主に粗粒度の認可を目的として設計されています（たとえば、あるアプリケーションへのアクセスをユーザーのグループメンバーシップに基づいて管理するなど）。この例では、細粒度のアクセス管理に使用しますが、それは必ずしも設計時に意図した目的ではありません（たとえば、ユーザーがアプリケーション内で特定のアクションを実行できるかなど）。
</Card>

すべてのユーザーは暗黙的に通常のユーザーとみなされますが、タイムシート管理者は`Admin`グループに割り当てられ、これによりタイムシートの承認が可能になります。Authorization Extension（認可拡張機能）では、グループを既存のグループメンバーシップにマッピングすることができます。

すべてのタイムシート管理者はActive Directoryの`Timesheet Administrators`グループに割り当てられ、これがタイムシートアプリケーション内の`Admin`グループに自動的にマッピングされます。

認可拡張機能をインストールすると、バックグラウンドでルールが作成され、以下の処理が行われます。

1. ユーザーのグループメンバーシップを決定する。
2. ユーザーのグループメンバーシップ情報を`app_metadata`の一部として保存する。
3. ユーザーのグループメンバーシップを送信されるトークンに追加する。
4. ユーザーが現在のアプリケーションへのアクセス権を付与されていることを確認する。

### 認可拡張機能をインストールする

認可拡張機能をインストールするには、Auth0 Dashboardの[［Extensions（拡張機能）］](https://manage.auth0.com/#/extensions)ビューに移動し、Auth0 Authorization拡張機能を選択してインストールします。

インストールが完了すると、［Installed Extensions（インストール済み拡張機能）］の下にアプリが表示されます。

リンクをクリックして拡張機能を初めて開くと、Auth0アカウントにアクセスするための許可を拡張機能に与えるよう求めるメッセージが表示されます。許可を与えると、Authorization Dashboard（認可ダッシュボード）にリダイレクトされます。

Authorization Dashboard（認可ダッシュボード）に移動したら、ナビゲーションメニューの［Groups（グループ）］に進み、「Admin」という新しいグループを作成します。

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0/docs/images/ja-jp/cdy7uua7fh8z/6zOF0mCrLV2rwdpxn9JD1e/5d6e227c4a96260856afd8f94c4212d9/create-admin-group.png" alt="undefined" />
</Frame>

グループが追加されたら、そのグループをクリックしてグループ管理セクションに進むことができます。［Group Mappings（グループマッピング）］タブに移動し、「`Timesheet Admins`」グループのすべてのActive Directoryユーザーを、先ほど作成した「`Admin`」グループにマッピングする新しいグループマッピングを追加します。

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0/docs/images/ja-jp/cdy7uua7fh8z/RaMHHJ1G9LoO5xoz3BJnN/b01c93948b1a54b599f1eb106bd8ef26/add-group-mapping.png" alt="undefined" />
</Frame>

**［Save（保存）］** をクリックすると、新しいマッピングが一覧表示されます。

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0/docs/images/ja-jp/cdy7uua7fh8z/1whRHGlsRhGhA6vcrsElsv/093716ca939c843729c3022c810ee6a7/view-group-mapping.png" alt="undefined" />
</Frame>

マッピングが構成されると、Active Directoryの「`Timesheet Admins`」グループのメンバーシップを維持するだけで、これらのユーザーは自動的にアプリケーション内の「`Admin`」グループにマッピングされます。

詳細については、[認可拡張機能に関するドキュメント](/docs/ja-jp/customize/extensions/authorization-extension)を参照してください。

### アプリケーション内で権限を強制する

認証拡張機能をインストールした時に、特定のユーザーに関連するすべての認可設定を含む`authorization`クレームを追加するAuth0ルールも作成されました。ユーザーのグループは、「`groups`」という`authorization`クレームのサブクレームとして追加され、ユーザーが所属するすべてのグループがこのクレームに配列として追加されます。以下は、グループが表示されたIDトークンのJSONペイロードの例です。

```json lines theme={null}
{
  "sub": "1234567890",
  "name": "John Doe",
  "authorization": {
    "groups": ["Admin"]
  }
}
```

したがってアプリケーションでは、ユーザーが認証されたときに返されるIDトークンをデコードし、ユーザーが所属するグループを`authorization`クレームから抽出する必要があります。その後、これらのグループを他のユーザー情報と共にユーザーのセッション内に保存し、それ以降、ユーザーのグループメンバーシップに基づいて、ユーザーが特定のアクションを実行する権限を持っているかどうか判断するためにクエリを実行することができます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  [ASP.NET Core](https://auth0.com/docs/architecture-scenarios/application/web-app-sso/implementation-aspnetcore#implement-admin-permissions)での実装を参照してください。
</Callout>
