1. ホーム
  2. authentication

[解決済み】OAuth2の「暗黙の」フローはとてもうまく機能しているのに、なぜ「認証コード」フローがあるのですか?

2022-03-28 06:53:43

質問

Implicitフローでは、リソースオーナー(ユーザー)がアクセス権を与えた後、クライアント(おそらくブラウザ)はアクセストークンを取得します。

しかし、quot;認証コードフローでは、クライアント(通常はWebサーバー)は、リソース所有者(すなわちユーザー)がアクセスした後に認証コードを取得するだけです。この認証コードを持って、クライアントは再度APIを呼び出し、client_idとclient_secretを認証コードとともに渡し、アクセストークンを取得します。 すべてここで説明されています .

どちらのフローも全く同じ結果、アクセストークンを生成します。しかし、quot;Implicit"のフローの方がはるかにシンプルです。

質問です。 Implicitフローで十分だと思うのですが、なぜわざわざAuthorization Codeフローを使うのですか?Webサーバにも"Implicit"を使用しない理由は何ですか?

提供側、クライアント側ともに手間がかかる。

解決方法は?

tl;dr: これはすべて、セキュリティ上の理由によるものです。

OAuth 2.0は、この2つの条件を満たしたかったのです。

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

詳細は以下。

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

での 暗黙のフロー の場合、アクセストークンはハッシュフラグメントとして直接渡されます (URL パラメータとしてではありません)。ハッシュフラグメントの重要な点は、ハッシュフラグメントを含むリンクをたどると、ブラウザだけがそのハッシュフラグメントを認識することです。ブラウザは、ハッシュフラグメントを直接目的地のウェブページ(リダイレクトURI/クライアントのウェブページ)に渡します。ハッシュ・フラグメントには、次のような性質があります。

  • HTTPリクエストの一部ではないので、サーバーに読み取られることはなく、そのため中間サーバーやルーターに傍受されることもありません(これは重要なポイントです)。
  • ブラウザ(クライアント側)にしか存在しないため、ハッシュの断片を読み取るには、ページ上で実行されるJavaScriptを使用するしかないのです。

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

また、暗黙のフローにはセキュリティ上の問題があり、例えば回避するためにさらなるロジックが必要になります。

  • 攻撃者は、別のウェブサイトやアプリのユーザーからアクセストークンを取得し(例えば、その人が別のウェブサイトやアプリの所有者である場合)、そのトークンを相手のウェブサイトで記録し、それをあなたのウェブサイトのURLパラメータとして渡し、あなたのウェブサイト上のユーザーになりすますことができる可能性があります。これを避けるには、アクセストークンに関連付けられたクライアントID(たとえばGoogleの場合はtokeninfoエンドポイント)をチェックして、トークンが自分のクライアントID(つまり自分のアプリ)で発行されたことを確認するか、IDTokenを使用している場合は署名をチェックします(ただしこれには自分のクライアントシークレットが必要です)。
  • 認証要求があなたのプロパティから発信されていない場合(Session Fixation攻撃と呼ばれます)、これを避けるために、あなたのウェブサイトからランダムなハッシュを生成し、それをクッキーに保存して、認証要求の状態のURLパラメータに同じハッシュを渡したいでしょう、ユーザーが戻ってきたとき、クッキーを使って状態のパラメータをチェックし、それが一致しなければなりません。

認証コードフロー なぜなら、URL パラメータは HTTP リクエストの一部だからです。したがって、暗号化された接続 (HTTPS) を使用していない場合、リクエストが通過する中間サーバー/ルーター (数百にも及ぶ可能性があります) はアクセストークンを読むことができ、いわゆる「中間者攻撃 (Man-in-the-middle attack)」が可能になります。

アクセストークンを URL パラメータに直接渡すことは理論的には可能ですが、認証サーバーはリダイレクト URI が TLS 暗号化された HTTPS であること、および「信頼できる」SSL 証明書(通常は無料ではない認証局からのもの)を使用して、転送先のサーバーが正当であることと HTTP 要求が完全に暗号化されていることを確認しなければならないでしょう。すべての開発者が SSL 証明書を購入し、ドメインに SSL を適切に設定することは、非常に面倒であり、採用が大幅に遅れると思われます。このため、中間的な1回限りの認証コード(quot;authorization code")を提供し、正当な受信者だけが交換できるようにし(クライアントの秘密が必要なので)、暗号化されていない取引でリクエストを傍受する潜在的ハッカーにはそのコードが役に立ちません(クライアント秘密を知らないからです)。

例えば、クライアントのウェブサイトのIPアドレスをハイジャックして、リダイレクト時にドメインを詐称するなど、潜在的な攻撃ベクトルが存在します。これは、暗黙のフローがアクセストークン(使用期間が限定されている)のみを付与し、リフレッシュトークン(使用期間が無制限)を付与しない理由の1つです。この問題を解決するために、可能な限りHTTPS対応のサーバーでウェブページをホストすることをお勧めします。