ソリューションの概要(Webアプリ + SSO)
このセクションでは、ID管理、使用するプロトコル、必要な認証フローの詳細など、実装するソリューションについて説明します。
ID管理
ExampleCo は、Identity as a Service(IDaaS)プロバイダーとしてAuth0を使用することを決定しました。この決定の理由は、会社がIDおよびアクセス管理のトレーニング、実装、保守にリソースを投入したくなかったためです。さらに、同社は将来的にこのソリューションにモバイルネイティブアプリとAPIを追加し、承認されたタイムシートを社内システムにプッシュする計画もあります。Auth0は、最小限の労力でアーキテクチャにこのような変更を組み込む柔軟性を提供します。
使用するプロトコル
次の決定は、OpenID Connect(OIDC)を使用したOAuth 2.0 とSAMLのどちらのプロトコルを使用するかという点に関係します。
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アプリを使用するため、認可コードフローを使用します。
フローは以下のようになります:
Webアプリ(OIDC用語ではクライアントと呼ばれます)は、ユーザーエージェント(ブラウザー)をAuth0(OIDC用語では認可サーバー)にリダイレクトして認証要求を開始します。
Auth0はユーザーを認証します(ユーザーエージェント経由)。ユーザーが初めてこのフローを通過すると、同意ページが表示され、アプリケーションに付与される権限(メッセージの投稿、連絡先の一覧表示など)がリストされます。ユーザーはサービスにログインし(すでにログインしていない場合)、アプリケーションアクセスを認可します。
ユーザーがアクセスを許可した場合、Auth0はクエリ文字列内の認可コードとともにユーザーエージェントをアプリケーションにリダイレクトします。
アプリケーションは、アプリケーションの資格情報(client_idおよびclient_secret)とともに認可コードをAuth0に送信し、トークンを要求します。
Auth0はアプリケーションを認証し(client_idおよびclient_secretを使用)、認可コードを検証します。有効な場合、Auth0はIDトークンで応答します。

フォーム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トークンの検証にはいくつかの手順が必要です:
IDトークンが暗号化されている場合は、アプリケーションが指定したキーとアルゴリズムを使用して復号化します。
OpenIDプロバイダーの発行者識別子は、
iss
(発行者)クレームの値と一致する必要があります。aud
(オーディエンス)クレームには、アプリケーションのclient_id
値が含まれている必要があります。IDトークンにアプリケーションが有効なオーディエンスとしてリストされていない場合、またはアプリケーションによって信頼されていない追加のオーディエンスが含まれている場合、IDトークンは拒否されなければなりません。IDトークンに複数のオーディエンスが含まれている場合、アプリケーションは
azp
クレームが存在することを確認する必要があります。azp
(承認された当事者)クレームが存在する場合、アプリケーションは、そのclient_id
がクレーム値であることを確認する必要があります。アプリケーションは、JWT
alg
ヘッダーパラメータで指定されたアルゴリズムを使用して、JWSに従ってIDトークンの署名を検証する必要があります。アプリケーションは発行者によって提供されたキーを使用する必要があります。alg
値は、RS256
のデフォルト、または登録時にid_token_signed_response_alg
パラメータでアプリケーションによって送信されたアルゴリズムである必要があります。JWT
alg
ヘッダーパラメータがHS256
、HS384
、HS512
,などのMACベースアルゴリズムを使用する場合、aud
(オーディエンス)クレームに含まれるclient_id
に対応するclient_secret
のUTF-8表現のオクテットが、署名を検証するためのキーとして使用されます。MACベースアルゴリズムの場合、aud
が複数値である場合、またはaud
値とは異なるazp
値が存在する場合、動作は未指定です。現在の時刻は、
exp
クレームによって表される時刻より前である必要があります。iat
クレームを使用すると、現在の時刻からかなり離れて発行されたトークンを拒否し、攻撃を防ぐためにnonce を保存する必要がある時間を制限できます。許容範囲はアプリケーションによって異なります。認証要求で
nonce
値が送信された場合、nonce
クレームが存在し、その値が認証要求で送信された値と同じであることを確認するためにチェックされる必要があります。アプリケーションは、リプレイ攻撃に備えてnonce
値をチェックする必要があります。リプレイ攻撃を検出するための正確な方法はアプリケーションによって異なります。acr
クレームが要求された場合、アプリケーションは主張されたクレーム値が適切であることを確認する必要があります。auth_time
クレームが、このクレームに対する特定の要求を通して、またはmax_age
パラメータを使用して要求された場合、アプリケーションはauth_time
クレーム値を確認し、最後のエンドユーザー認証から経過した時間が長すぎると判断した場合は再認証を要求する必要があります。