「暗黙的」フローがうまく機能するのに、OAuth2 にはなぜ「認証コード」フローがあるのでしょうか? 質問する

「暗黙的」フローがうまく機能するのに、OAuth2 にはなぜ「認証コード」フローがあるのでしょうか? 質問する

「暗黙的」フローでは、リソース所有者 (つまりユーザー) がアクセス権を付与した後、クライアント (おそらくブラウザ) はアクセス トークンを取得します。

ただし、「認証コード」フローでは、クライアント (通常は Web サーバー) は、リソース所有者 (つまり、ユーザー) がアクセスを許可した後にのみ認証コードを取得します。その認証コードを使用して、クライアントは API に別の呼び出しを行い、認証コードとともに client_id と client_secret を渡してアクセス トークンを取得します。ここにすべて詳しく説明されています

どちらのフローも結果は同じで、アクセス トークンが生成されます。ただし、「暗黙的」フローの方がはるかにシンプルです。

質問: 「暗黙的」フローが問題なく動作しているように見えるのに、なぜ「認証コード」フローにこだわるのでしょうか? Web サーバーに「暗黙的」フローを使用しないのはなぜですか?

プロバイダーとクライアントの両方にとって、作業が増えます。

ベストアンサー1

要約:これはすべてセキュリティ上の理由によるものです。

OAuth 2.0 では、次の 2 つの基準を満たすことを目指しました。

  1. すべての開発者が SSL 対応サーバーを持っているわけではなく、持っていたとしても必ずしも適切に構成されているとは限らないため (自己署名されていない、信頼できる SSL 証明書、同期されたサーバー クロックなど)、開発者が非 HTTPS リダイレクト URI を使用できるようにする必要があります。
  2. ハッカーがリクエストを傍受してアクセス トークンやリフレッシュ トークンを盗むことがないようにする必要があります。

詳細は以下の通りです。

暗黙的なフローは、セキュリティ上の理由により、ブラウザ環境でのみ可能です。

暗黙的フローでは、アクセス トークンはハッシュ フラグメントとして直接渡されます (URL パラメータとしてではありません)。ハッシュ フラグメントに関する重要な点の 1 つは、ハッシュ フラグメントを含むリンクをたどると、そのハッシュ フラグメントを認識するのはブラウザーのみであるということです。ブラウザーは、ハッシュ フラグメントを宛先 Web ページ (リダイレクト URI / クライアントの Web ページ) に直接渡します。ハッシュ フラグメントには次のプロパティがあります。

  • これらは HTTP リクエストの一部ではないため、サーバーでは読み取れず、中間サーバー/ルーターによって傍受されることもありません (これは重要です)。
  • これらはブラウザ(クライアント側)にのみ存在するため、ハッシュ フラグメントを読み取る唯一の方法は、ページ上で実行される JavaScript を使用することです。

これにより、中間サーバーによって傍受されるリスクなしに、アクセス トークンをクライアントに直接渡すことが可能になります。ただし、これはクライアント側でのみ可能であり、アクセス トークンを使用するにはクライアント側で JavaScript を実行する必要があるという注意点があります。

暗黙的なフローには、回避/回避するための追加のロジックを必要とするセキュリティ上の問題もあります。たとえば、

  • 攻撃者は、別の Web サイト/アプリのユーザーからアクセス トークンを取得し (そのユーザーが別の Web サイト/アプリの所有者であるとします)、そのトークンを自分の Web サイトに記録し、それを URL パラメータとして自分の Web サイトに渡すことで、自分の Web サイトでユーザーになりすますことができます。これを回避するには、アクセス トークンに関連付けられたクライアント ID (たとえば、Google の場合は tokeninfo エンドポイントを使用できます) をチェックして、トークンが自分のクライアント ID (つまり、自分のアプリによって) で発行されたことを確認するか、IDToken を使用している場合は署名をチェックする必要があります (ただし、クライアント シークレットが必要です)。
  • 認証リクエストが独自のプロパティから発信されたものでない場合 (セッション固定攻撃と呼ばれる)、これを回避するには、Web サイトからランダムなハッシュを生成し、それを Cookie に保存して、同じハッシュを認証リクエストの状態 URL パラメータに渡します。ユーザーが戻ってきたときに、状態パラメータを Cookie でチェックし、一致する必要があります。

認証コード フローでは、URL パラメータが HTTP リクエストの一部であるため、アクセス トークンを URL パラメータで直接渡すことはできません。そのため、暗号化された接続 (HTTPS) を使用していない場合、リクエストが通過する中間サーバー/ルーター (数百になる場合があります) がアクセス トークンを読み取ることができ、中間者攻撃と呼ばれる攻撃が発生する可能性があります。

アクセス トークンを URL パラメータで直接渡すことは理論上は可能ですが、認証サーバーはリダイレクト URI が TLS 暗号化と「信頼できる」SSL 証明書 (通常は無料ではない証明機関のもの) を使用した HTTPS を使用していることを確認し、宛先サーバーが正当であり、HTTP 要求が完全に暗号化されていることを確認する必要があります。すべての開発者が SSL 証明書を購入し、ドメインで SSL を適切に構成することは非常に面倒で、採用が大幅に遅れることになります。このため、正当な受信者だけが交換できる (クライアント シークレットが必要なため) 中間の 1 回限りの「認証コード」が提供され、暗号化されていないトランザクションで要求を傍受する潜在的なハッカーにとってこのコードは役に立ちません (クライアント シークレットを知らないため)。

また、暗黙的なフローは安全性が低いという意見もあります。リダイレクト時にドメインを偽装するなど、潜在的な攻撃ベクトルが存在するためです。たとえば、クライアントの Web サイトの IP アドレスをハイジャックするなどです。暗黙的なフローではアクセス トークン (使用時間が限られているはず) のみが許可され、リフレッシュ トークン (使用時間が無制限) は許可されないのは、これが理由の 1 つです。この問題を解決するには、可能な限り、Web ページを HTTPS 対応のサーバーでホストすることをお勧めします。

おすすめ記事