OAuth承認コードと暗黙的なワークフローの違いは何ですか?それぞれをいつ使用するのですか?


165

OAuth 2.0には複数のワークフローがあります。2つについていくつか質問があります。

  1. 承認コードフロー -ユーザーがクライアントアプリからログインすると、承認サーバーが承認コードをアプリに返します。次に、アプリは認証コードをアクセストークンと交換します。
  2. 暗黙的な付与フロー -ユーザーはクライアントアプリからログインし、承認サーバーはクライアントアプリに直接アクセストークンを発行します。

セキュリティの点で2つのアプローチの違いは何ですか?どちらがより安全で、なぜですか?

サーバーがアクセストークンを直接発行できるときに、1つのワークフローに追加の手順(トークンの認証コードの交換)が追加される理由がわかりません。

クライアントアプリが資格情報を安全に保つことができる場合、承認コードフローが使用されると、さまざまなWebサイトが述べています。どうして?


回答:


204

これaccess_tokenは、保護されたリソース(API)を呼び出すために必要なものです。承認コードフローでは、次の2つの手順で取得します。

  1. ユーザーは認証し、 codeしてAPIコンシューマー(「クライアント」と呼ばれる)に。
  2. API(通常はWebサーバー)の「クライアント」は、code1で取得したをと交換access_tokenし、client_idおよびclient_secret
  3. 次に、を使用してAPIを呼び出すことができますaccess_token

つまり、APIを介して表示されるリソースを所有するユーザーと、APIを使用するクライアント(Webアプリなど)の二重チェックがあります。両方とも、アクセスが許可されることが検証されています。ここでのOAuthの「承認」の性質に注意してください。ユーザーは自分のリソースへのアクセスを(code認証後に返されたものを通じて)アプリに許可します。access_tokenし、ユーザーの代わりに呼び出します。

暗黙のフローでは、ステップ2は省略されます。したがって、ユーザー認証の後、access_tokenが直接返され、リソースへのアクセスに使用できます。APIは、誰がそのAPIを呼び出しているかを認識していません。誰でもaccess_token缶を、前の例ではWebアプリしかできません(通常、内部には誰もアクセスできません)。

暗黙的な流れは、通常、記憶シナリオで使用されるclient idclient secret(多くはとにかくそれを行うが、例えばデバイス)は推奨されません。それが免責事項の意味です。人々はクライアントコードにアクセスできるため、資格を取得してリソースクライアントになりすますことができます。暗黙的なフローでは、すべてのデータが揮発性であり、アプリに何も保存されていません。


説明ありがとうございますが、なぜ別の認証コードフローが必要なのかわかりません。暗黙のフロー(access_token)と更新トークンによってサーバーで同じ結果に到達できます。暗黙的なフローの唯一のセキュリティ上の考慮事項は、access_codeの有効期間が短く、サーバー間で使用できないことです。OK、しかしリフレッシュトークンはこの問題を解決します。なぜauth_codeフローを使用し、サーバー上でそれによってaccess_tokenをリクエストしてaccess_codeを取得する必要があるのですか?
Mohammad Nikravan 2016

まあ...それはプロトコルがどのように機能するかです。どちらか一方のセキュリティ上のメリットの詳細については、仕様の脅威分析をご覧ください。
Eugenio Pace

元の答えが5年以上前のものであることは知っていますが、これは私が今まで読んだ中で最も単純でクリーンな説明です。ありがとう@EugenioPace
Taha Ahmad

1
@ Madnik7G理由は、この回答が(美しく)説明するものと直交しているため、第三者が関与している可能性があります。フロー全体はユーザーエージェント(例:ブラウザー)によって調整されますが、最終的に承認サーバー(例: "Facebookでログイン")はクライアント(たとえば、サーバー側のBFF)と直接通信し、最終的にリソースにアクセスするため、ユーザーエージェントが直接アクセスすることはありません。
Daniel Langdon

ありがとう!はい、ブラウザとAS 9の3つの通信が行われています。フェイスブック)。それが/authorizeリクエストです。API(別名クライアント)を呼び出そうとしているブラウザーとWebサイト。これは、認証が成功した後にASから返されるredirect_uri+ codeです。最後に、クライアントは交換、舞台裏でASを呼び出すcodeためaccess_token。これはtoken endpoint文献にあります。一般に、ASは誰にも電話しません。それは常に返信します。
Eugenio Pace

52

上記の回答で明らかにされていないと思われるものをここに追加します。

  • Authorization-Code-Flowにより、最終的なアクセストークンが到達せず、ブラウザ/アプリを備えたマシンに保存されることはありません。一時的な認証コードはブラウザ/アプリでマシンに与えられ、サーバーに送信されます。その後、サーバーはそれをフルアクセストークンと交換し、APIなどにアクセスできます。ブラウザーを持つユーザーは、トークンを持つサーバーを介してのみAPIにアクセスできます。
  • 暗黙的なフローが関与できるのは2つのパーティのみであり、最終的なアクセストークンはブラウザ/アプリを使用してクライアントに保存されます。このブラウザ/アプリが危険にさらされている場合、危険である可能性のある認証トークンも危険にさらされます。

tl; drは、ユーザーマシンがトークンを保持することを信頼していない場合は暗黙フローを使用しませ信頼して、自分のサーバー信頼している。


12
re:ブラウザーを持つユーザーは、トークンを持つサーバーを介してのみAPIにアクセスできます。 ただし、サーバーはブラウザーに何かを送信て、サーバー側で保持されているトークンにインバウンド要求を関連付けることができるようにする必要があります。お好みでクッキー。サーバーがブラウザで実行されているJSにトークンを送信しない場合、サーバーが特定のクライアントに代わって動作できるようにするために、(ブラウザー)クライアントがサーバーに渡す必要がある何かを送信する必要があります。
Cheeso

はい、クッキーです。したがって、クロスサイトリクエストフォージェリから保護されるようにサーバーとブラウザクライアントを設定する必要があります。
マルセル

@Marcel私は、コードを取得したら、どのようにしてどこで交換が行われaccess_token、の助けを借りて実際の取引が行われるかを知りたいと思いauthorization codeます。
chirag soni

14

両者の違いは次のとおりです。

  1. 暗黙的フローでは、トークンは「#」記号付きのリダイレクトURLを介して直接返され、これは主にサーバー側を持たないJavaScriptクライアントまたはモバイルアプリケーションで使用され、一部の実装ではクライアントが秘密を提供する必要はありません。 。

  2. 承認コードフローでは、コードは「?」で返されます サーバー側で読み取り可能にするには、サーバー側で今回はクライアントシークレットをURLにトークン化して、承認サーバーからjsonオブジェクトとしてトークンを取得する必要があります。これを処理し、ユーザーのトークンを自分のシステムのプロファイルと共に保存できるアプリケーションサーバーがある場合に使用され、主に一般的なモバイルアプリケーションに使用されます。

そのため、クライアントアプリケーションの性質に依存します。クライアントのシークレットを要求し、非常に安全な接続で認証サーバーとクライアントアプリケーション間でトークンを送信できるため、もう1つの安全な「認証コード」を使用でき、認証プロバイダーは「認証コード」のみを使用するように一部のクライアントを制限し、暗黙を許可しない


認証コードは、Facebookの場合、サーバー側に10分間保存されます。これは、2012年12月5日の変更でリリースされました。私の質問は主に、セキュリティとパフォーマンスの点で2つの違いは何ですか?私は両方のフローが何をするのか知っていますが、認証コードを使用する利点は何ですか-ワークフローに1つのステップを追加します。
divyanshm 2013年

トークンをユーザーアプリケーションに直接送信しないため、クライアントアプリケーションと承認サーバーの間の接続はユーザーから隠されます。前述したように、ユーザーからクライアントアプリケーションへのチャネルとは異なる非常に安全なチャネルである可能性があります。
Bassem Reda Zohdy 2013年

認証サーバーで2回認証サーバーにアクセスしてパフォーマンスが向上するため、時間がかかります。また、クライアントサーバーがユーザートークンを保存するため、時間も長くなります。
Bassem Reda Zohdy 2013年

2
ああ大丈夫!これを見落としたのかもしれません。したがって、基本的に、認証コードフローは、サーバー全体がクライアントであるシステムで使用されます。ブラウザがリクエストを行い、コードを取得します。コードは、リソースサーバーに安全に接続するクライアントサーバーに送信されます。私はそれを正しく理解していますか?アクセストークンがエンドユーザーのマシンに到達することはありませんか?
divyanshm 2013年

1
アクセストークンがエンドユーザーのマシンに到達することはありませんか?はい、クライアントアプリケーションサーバーでプロファイルにリンクされています。
Bassem Reda Zohdy 2013年

4

暗黙的な付与は、2つの異なる点を除いて、許可コード付与に似ています。

すべてのアプリケーションコードとストレージに簡単にアクセスできるため、クライアントを秘密にできないユーザーエージェントベースのクライアント(単一ページのウェブアプリなど)で使用することを目的としています。

次に、認証サーバーがアクセストークンと交換される認証コードを返す代わりに、認証サーバーがアクセストークンを返します。

詳細はこちら http://oauth2.thephpleague.com/authorization-server/which-grant/


1
そのリンクをありがとう、それは私がそれぞれの助成金の種類とそれぞれを選ぶ時期の違いを理解するのに役立ちました。
フランソワ・POYER

3

暗黙の流れ

メリット

  • 実装が最も簡単

短所

  • ブラウザに表示されるアクセストークン
  • アクセストークンの出所を特定できません
  • アクセストークンに有効期限はありません(Googleのポリシーによる)

承認コードの流れ

メリット

  • 最も安全
  • アクセストークンと更新トークンは、共有シークレットがわかっている場合にのみ作成できます
  • 新しいセキュリティとUX機能が利用可能になったときに、それらを強化できます。

短所

  • 複数の認証エンドポイントを実装する必要があります

引用:https : //developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows


2

上記の回答から学んだポイントを要約し、私自身の理解をいくつか加えましょう。

承認コードの流れ!!!

  • OAuthクライアントとして機能するウェブアプリケーションサーバーがある場合
  • 長期間アクセスしたい場合
  • データにオフラインでアクセスしたい場合
  • アプリが行うAPI呼び出しに責任がある場合
  • OAuthトークンを漏らしたくない場合
  • アプリケーションがデータへのアクセスを必要とするたびに認証フローを実行したくない場合。注:Implicit Grantフローではリフレッシュトークンを利用できないため、承認サーバーがアクセストークンを定期的に期限切れにする場合、アプリケーションはアクセスが必要なときに常に承認フローを実行する必要があります。

暗黙的な付与フロー!!!

  • OAuthクライアントとして機能するWebアプリケーションサーバーがない場合
  • 長期間のアクセスが必要ない場合、つまりデータへの一時的なアクセスのみが必要です。
  • アプリが実行されているブラウザを信頼していて、信頼されていないユーザーにアクセストークンが漏洩するという懸念が限られている場合。

2

どちらがより安全で、なぜですか?

どちらも安全で、使用している環境によって異なります。

サーバーがアクセストークンを直接発行できるときに、1つのワークフローに追加の手順(トークンの認証コードの交換)が追加される理由がわかりません。

簡単です。あなたのクライアントは安全ではありません。詳しく見てみましょう。

に対してアプリケーションを開発していると考えてInstagram API、APPを登録して必要なInstagramものAPI'sを定義します。Instagramを提供しclient_idclient_secrect

あなたのウェブサイトであなたは言うリンクを設定しました。「来て、私のアプリケーションを使用する」。これをクリックすると、Webアプリケーションはを2回呼び出す必要がありますInstagram API

FirstInstagram Authentication Server以下のパラメータでリクエストを送信します。

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

あなたは送信しませんclient_secret、あなたはクライアントを信頼することができませんでした(あなたとあなたのアプリケーションを使用しようとするユーザーと彼のブラウザ)。クライアントは、URLまたはJavaスクリプトを確認して、client_secrect簡単に見つけることができます。これが、別のステップが必要な理由です。

あなたは受けるcodestatecodeここでtemporary、任意の場所に保存されていません。

次にsecondInstagram API(サーバーから)を呼び出します

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

呼び出しがサーバーから行われるclient_secretcode、ユーザーがclient_idリソースの使用を許可したことを示す安全な方法(これがどのように表示されるか)を使用できます。

それに応じて、 access_token


1

実用的な観点(私が理解したこと)から、Authzコードフローを持つ主な理由は次のとおりです。

  1. 更新トークンのサポート(ユーザーに代わってアプリによる長期アクセス)、暗黙的にはサポートされていません:参照:https : //tools.ietf.org/html/rfc6749#section-4.2
  2. リソース所有者が提供するアクセスを制御できる場所である同意ページのサポート(Googleに表示されるアクセス許可/承認ページの種類)。暗黙の中に同じことはありません。セクションを参照してください:https : //tools.ietf.org/html/rfc6749#section-4.1、ポイント(B)

「認可サーバーはリソースオーナーを(ユーザーエージェント経由で)認証し、リソースオーナーがクライアントのアクセスリクエストを許可するか拒否するかを確立します。」

それとは別に、更新トークンを使用すると、アプリはユーザーデータに長期間アクセスできます。


0

これまでに説明されていない2つの重要な点があるように思われます。これにより、Authorization Code Grant Typeの迂回がセキュリティを強化する理由が説明されます。

簡単な説明:承認コード付与タイプは、ブラウザーの履歴から機密情報を保持し、トークンの送信は、承認サーバーのHTTPS保護にのみ依存します。

長いバージョン:

以下では、RFCで定義されているOAuth 2の用語を使用します(簡単に読みます):リソースサーバークライアント承認サーバーリソース所有者

サードパーティのアプリ(=クライアント)がGoogleアカウント(=リソースサーバー)の特定のデータにアクセスすることを想像してください。GoogleがOAuth 2を使用しているとしましょう。あなたはGoogleアカウントのリソース所有者ですが、現在はサードパーティアプリを操作しています。

まず、クライアントがブラウザを開いて、Google認証サーバーの安全なURLに送信します。次に、アクセスのリクエストを承認すると、認証サーバーは、クエリ文字列に認証コードを含めて、以前に与えられたリダイレクトURLに返信します。次に、2つの重要なポイントについて説明します。

  1. このリダイレクトのURLは、ブラウザの履歴に残ります。したがって、ここでは、長期間有効で直接使用できるアクセストークンは必要ありません。存続期間の短い認証コードは、歴史的にはそれほど危険ではありません。Implicit Grantタイプで、トークンが履歴に記録されることに注意してください。
  2. このリダイレクトのセキュリティは、Googleの証明書ではなく、クライアントの HTTPS証明書に依存します。したがって、クライアントの送信セキュリティを追加の攻撃ベクトルとして取得します(これを回避するには、クライアントはJavaScript以外である必要があります。それ以外の場合は、コードがネットワークを通過しないフラグメントURLを介して認証コードを送信できます。これが、フラグメントURLを使用するImplicit Grant Type がJavaScriptクライアントに推奨されてた理由である可能性がありますが、それもはや推奨されません。

承認コード付与タイプでは、クライアントから承認サーバーへの呼び出しによってトークンが最終的に取得されます。この場合、送信セキュリティは承認サーバーにのみ依存し、クライアントには依存しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.