ソリューションの概要(Webアプリ + SSO)

このセクションでは、ID管理、使用するプロトコル、必要な認証フローの詳細など、実装するソリューションについて説明します。

ID管理

ExampleCo は、Identity as a Service(IDaaS)プロバイダーとしてAuth0を使用することを決定しました。この決定の理由は、会社がIDおよびアクセス管理のトレーニング、実装、保守にリソースを投入したくなかったためです。さらに、同社は将来的にこのソリューションにモバイルネイティブアプリとAPIを追加し、承認されたタイムシートを社内システムにプッシュする計画もあります。Auth0は、最小限の労力でアーキテクチャにこのような変更を組み込む柔軟性を提供します。

使用するプロトコル

次の決定は、OpenID Connect(OIDC)を使用したOAuth 2.0SAMLのどちらのプロトコルを使用するかという点に関係します。

OpenID Connectは、OAuth 2.0ファミリーの仕様に基づいた認証プロトコルです。OAuth 2.0プロトコルを介して配信されるシンプルなJSON IDトークン(JWT)を使用します。

OAuthとOpenID Connect(OIDC)

OAuth 2.0とOpenID Connect(OIDC)はよく同じものとして捉えられますが、これは間違いです。__OAuth 2.0__は、1つのWebサイト(消費者またはアプリケーション)を認可させるプロトコルで、別のWebサイト(リソースサーバーまたはプロバイダー)からあなたのデータにアクセスできます。たとえば、Webサイトを認可して、Dropboxアカウントのいくつかのファイルにアクセスしたいとします。WebサイトがDropboxにリダイレクトさせ、ファイルへのアクセスを提供するべきかどうかを聞きます。同意する場合、WebサイトはDropboxのファイルにアクセスできるように認可されます。本質的に、OAuth 2.0はリソースアクセスと共有に関連しています。一方で、__OpenID Connect__は、OAuth 2.0プロトコル上に構築されたシンプルなIDレイヤーです。一度に複数サイトへのログインが可能になります。OIDCを使用してWebサイトにログインするたびに、自分のOpenIDサイトにリダイレクトされ、そこでログインすると元のWebサイトに戻されます。本質的に、OIDCはユーザー認証と関係があります。

SAMLは、信頼できる当事者間の認証と認可の両方を提供するXMLベースのプロトコルです。

SAMLと比較すると、OpenID Connectは軽量で扱いが簡単です。SAMLは実績があり、強力で柔軟性がありますが、このアプリの要件では、その柔軟性と強力さは必要ありません。IDフェデレーション(SAMLを採用する最も説得力のある理由の1つ)もここでは必要ありません。また、IDフェデレーションが必要になった場合でも、AD(LDAP を使用)を処理するのと同じ方法でAuth0によって簡単に処理できます。

これらの理由から、ExampleCoは実装にOpenID Connectを使用します。

認証フロー

OpenID Connectは、認証のために複数のフローをサポートします。このシナリオでは通常のWebアプリを使用するため、認可コードフローを使用します。

フローは以下のようになります:

  1. Webアプリ(OIDC用語ではクライアントと呼ばれます)は、ユーザーエージェント(ブラウザー)をAuth0(OIDC用語では認可サーバー)にリダイレクトして認証要求を開始します。

  2. Auth0はユーザーを認証します(ユーザーエージェント経由)。ユーザーが初めてこのフローを通過すると、同意ページが表示され、アプリケーションに付与される権限(メッセージの投稿、連絡先の一覧表示など)がリストされます。ユーザーはサービスにログインし(すでにログインしていない場合)、アプリケーションアクセスを認可します。

  3. ユーザーがアクセスを許可した場合、Auth0はクエリ文字列内の認可コードとともにユーザーエージェントをアプリケーションにリダイレクトします。

  4. アプリケーションは、アプリケーションの資格情報(client_idおよびclient_secret)とともに認可コードをAuth0に送信し、トークンを要求します。

  5. Auth0はアプリケーションを認証し(client_idおよびclient_secretを使用)、認可コードを検証します。有効な場合、Auth0はIDトークンで応答します。

undefined

フォームPOST応答モード

別の方法としては、__OAuth 2.0 Form Post Response Mode__に従ってresponse_type=id_token&response_mode=form_postを使用することもできます。response_type=id_tokenの要求パラメータのため、応答には認可コードではなくIDトークンが直接含まれています。一方、response_mode=form_postはIDトークンを残りの認可応答パラメータと共にHTMLフォーム値としてエンコードし、ユーザーエージェントで自動的に送信されます。これにより、最適化された認証フロー(コードとIDトークンを交換する必要なし)を持つことができますが、アプリを実装するために使用しているテクノロジーがこれをサポートしていることをご確認ください(ASP .NET Core ミドルウェアはサポートしています)。詳細は、「OAuth 2.0フォームPOST応答モードの仕様」をご覧ください。

ID Token(IDトークン)](コードサンプルでは通常id_tokenと呼ばれます)は、IDデータを含むJSON Webトークン(JWT)です。これはアプリケーションによって使用され、ユーザーの名前、メールなどのユーザー情報を取得するために使用され、通常はUI表示に使用されます。

トークンについての詳細

トークンは、トークンベースの認証で使用される英数字の文字列です。ユーザーはユーザー名とパスワードで認証し、引き換えにそこから使用できるトークンを取得できるようになります。トークンの有効期間は限られています。

__JSON Webトークン(JWTs)__は、JSON Webトークンスタンダードに準拠するトークンで、クレーム形成のIDについての情報を含みます。自己完結型であるため、受信者はサーバーを呼び出してトークンを検証する必要がありません。JWTはシークレット(__HMAC__アルゴリズムの)または__RSA__を使用した公開鍵/秘密鍵のペアを使用して署名することができます。JWTについての詳細はこちらです。IDトークン(JWT)は、業界基準(IETF RFC 7519)に準拠しており、ヘッダー、ボディ、署名の3部構成です。- ヘッダーは、トークンのタイプとトークンのコンテンツに使用されるハッシュ化アルゴリズムを含みます。- ボディは、ペイロードとも呼ばれ、ユーザーについてのIDクレームを含みます。トークンの発行者、トークンのサブジェクト(クレームの対象)、発行時刻などの登録済み名を持つクレームがあります。その他の名前のクレームを追加することができますが、JWTをURLのサイズ制限内に保つために注意する必要があります。- 署名は、JWTの受信者によって使用され、JWTに含まれる情報の整合性を検証するために署名を使用します。

IDトークンの検証方法

IDトークンの検証にはいくつかの手順が必要です:

  1. IDトークンが暗号化されている場合は、アプリケーションが指定したキーとアルゴリズムを使用して復号化します。

  2. OpenIDプロバイダーの発行者識別子は、iss(発行者)クレームの値と一致する必要があります。

  3. aud(オーディエンス)クレームには、アプリケーションのclient_id値が含まれている必要があります。IDトークンにアプリケーションが有効なオーディエンスとしてリストされていない場合、またはアプリケーションによって信頼されていない追加のオーディエンスが含まれている場合、IDトークンは拒否されなければなりません。

  4. IDトークンに複数のオーディエンスが含まれている場合、アプリケーションはazpクレームが存在することを確認する必要があります。

  5. azp(承認された当事者)クレームが存在する場合、アプリケーションは、そのclient_idがクレーム値であることを確認する必要があります。

  6. アプリケーションは、JWTalgヘッダーパラメータで指定されたアルゴリズムを使用して、JWSに従ってIDトークンの署名を検証する必要があります。アプリケーションは発行者によって提供されたキーを使用する必要があります。

  7. alg値は、RS256のデフォルト、または登録時にid_token_signed_response_algパラメータでアプリケーションによって送信されたアルゴリズムである必要があります。

  8. JWTalgヘッダーパラメータがHS256HS384HS512,などのMACベースアルゴリズムを使用する場合、aud(オーディエンス)クレームに含まれるclient_idに対応するclient_secretのUTF-8表現のオクテットが、署名を検証するためのキーとして使用されます。MACベースアルゴリズムの場合、audが複数値である場合、またはaud値とは異なるazp値が存在する場合、動作は未指定です。

  9. 現在の時刻は、expクレームによって表される時刻より前である必要があります。

  10. iatクレームを使用すると、現在の時刻からかなり離れて発行されたトークンを拒否し、攻撃を防ぐためにnonce を保存する必要がある時間を制限できます。許容範囲はアプリケーションによって異なります。

  11. 認証要求でnonce値が送信された場合、nonceクレームが存在し、その値が認証要求で送信された値と同じであることを確認するためにチェックされる必要があります。アプリケーションは、リプレイ攻撃に備えてnonce値をチェックする必要があります。リプレイ攻撃を検出するための正確な方法はアプリケーションによって異なります。

  12. acrクレームが要求された場合、アプリケーションは主張されたクレーム値が適切であることを確認する必要があります。

  13. auth_timeクレームが、このクレームに対する特定の要求を通して、またはmax_ageパラメータを使用して要求された場合、アプリケーションはauth_timeクレーム値を確認し、最後のエンドユーザー認証から経過した時間が長すぎると判断した場合は再認証を要求する必要があります。