OAuth 2の暗黙的な許可タイプの目的は何ですか?


254

何らかの盲点があるかどうかはわかりませんが、OAuth 2仕様を何度も読み、メーリングリストのアーカイブをよく読みました。また、暗黙の許可の理由についてはまだよくわかりません。アクセストークンを取得するためのフローが開発されました。Authorization Code Grantと比較すると、それほど説得力のある理由もなく、クライアント認証をあきらめているようです。これはどのようにして(仕様を引用するために)スクリプト言語を使用してブラウザに実装されたクライアント向けに最適化されていますか?

どちらのフローも同じように始まります(ソース:http : //tools.ietf.org/html/draft-ietf-oauth-v2-22):

  1. クライアントは、リソース所有者のユーザーエージェントを認証エンドポイントに送信することでフローを開始します。
  2. 認可サーバーは、リソースオーナーを(ユーザーエージェント経由で)認証し、リソースオーナーがクライアントのアクセス要求を許可するか拒否するかを確立します。
  3. リソースの所有者がアクセスを許可すると、認証サーバーは以前に(リクエスト内またはクライアントの登録時に)提供されたリダイレクトURIを使用してユーザーエージェントをクライアントにリダイレクトします。
    • リダイレクトURIには認証コード(認証コードフロー)が含まれています
    • リダイレクトURIには、URIフラグメントにアクセストークンが含まれます(暗黙的なフロー)。

ここで、フローが分割されます。どちらの場合も、この時点でのリダイレクトURIは、クライアントがホストするいくつかのエンドポイントに対するものです。

  • 承認コードフローでは、ユーザーエージェントがURIの承認コードでそのエンドポイントに到達すると、そのエンドポイントのコードが、必要に応じて使用できるアクセストークンのクライアント資格情報と共に承認コードを交換します。たとえば、ページ上のスクリプトがアクセスできるWebページにそれを書き込むことができます。
  • 暗黙的フローは、このクライアント認証ステップを完全にスキップし、クライアントスクリプトを含むWebページをロードするだけです。アクセストークンが過剰に渡されないようにするURLフラグメントには、ここにかわいいトリックがありますが、最終的な結果は基本的に同じです。クライアントがホストするサイトは、アクセストークンを取得できるスクリプトを含むページを提供します。

したがって、私の質問:クライアント認証手順をスキップすることで、ここで何が得られましたか?



5
前のコメントのリンクは無効です。こちらが更新されたものです
AndrewR

3
私はここですべての回答を読みましたが、アクセストークンを取得するためにプライベートクライアントシークレットを必要としないことでセキュリティを確保できる方法がわかりません。TrustedAppDeveloperがTrustedPopularAppをリリースして、ユーザーが暗黙の許可を使用してパーミッションを(たとえばTwitter oauthを使用して)付与できるとします。私がEvilAppDeveloperの場合、暗黙の許可要求でclient_idとしてTrustedPopularAppIdを渡すアプリを作成してから、ユーザーに代わってアクション(フィードのスパム送信など)を実行すると、TrustedPopularAppからのように見えるようになります。 ?
adevine

アデバインと同じことかな。しかし、暗黙の付与要求を必要とする最も可能性の高いアプリは、すべて取得できるため、追加の認証は必要ありません。
2015

13
@adevine TrustedPopularAppがTwitterからのコールバックを受信できなかったため、シナリオのEvilAppがTwitterに認証されなかった理由は、クライアントIDの登録時に定義されたURIに常に送信されることです
Ivan

回答:


196

ここに私の考えがあります:

認証コードフローでの認証コード+トークンの目的は、トークンとクライアントシークレットがサーバー間を移動するため、リソース所有者に決して公開されないことです。

一方、暗黙的な許可フローは、完全にJavaScriptを使用して実装され、リソース所有者のブラウザで実行されているクライアント用です。このフローを使用するためにサーバー側のコードは必要ありません。次に、リソース所有者のブラウザですべてが発生した場合、トークンとクライアントシークレットは引き続きリソース所有者と共有されるため、認証コードとクライアントシークレットを発行しても意味がありません。認証コードとクライアントシークレットを含めると、実際のセキュリティを追加することなく、フローが複雑になります。

それで、「何が得られたのか」という答えです。「シンプル」です。


4
ありがとう。これは、承認コードフローではリソース所有者がアクセストークンを見る必要がないのに対して、JavaScriptクライアントでは避けられないという点で良い点です。ただし、認証コードフローを使用して、JavaScriptクライアントからクライアントシークレットを保持することもできます。アクセストークンを認証して取得した後、サーバー側のコードがトークンをJavaScriptクライアントに渡します。しかし、私が今見ているのは、暗黙の許可フローにより、FacebookのようなJavaScript OAuth SDKの配布が可能になり、開発者が独自のOAuthコードを完全に記述する必要がなくなるということです。
Dan Taflin、2011年

3
承認コードフローにより、クライアントはトークンを保存して再利用できます。暗黙的フローでは、常にそのオプションがあるわけではないため、暗黙的フローはセキュリティのレベルと利便性の間の実用的な選択です。
PålOliver

2
これは半分しか答えず、「失われたもの」は何ですか?
EralpB 2017年

3
私はこれが包括的な答えだとは思いません。暗黙のフローは単純さの利点を得ることを意図したものではなく、クライアント側アプリのセキュリティの懸念を危うくすることを目的としています。Auth codeとともに、client_idおよびclient_secretを使用して、長時間のログインと「オフラインログイン」のためにトークンを更新できる信頼できるクライアントを識別します。ただし、クライアント側のアプリでは、各クライアントを登録する方法がないため、ユーザー情報に一時的にアクセスするための「単純化された」暗黙的な付与タイプ
Chen Xie

1
クライアントシークレットを含めると、フローが複雑になるだけでなく、安全性が低下します。クライアントシークレットは、クライアント側のコード内で列挙する必要がある場合はシークレットではないため、インターネットに公開されます。クライアントIDが暗黙的なフローでのみ使用されている場合、これは問題ではありません。ただし、更新トークンまたは承認コードの付与のためにプラットフォームの他の場所でも使用されている場合、対応するシークレットを公開することは大きな問題です。
Ataraxia

94

単純化のためではなく、セキュリティ上の理由からそこにあります。

ユーザーエージェントクライアントの違いを考慮する必要があります

ユーザーエージェントは、ユーザー(「リソースオーナー」)がシステムの他の部分(認証サーバーとリソースサーバー)と通信するためのソフトウェアです。

クライアントは、リソースサーバー上のユーザーのリソースにアクセスするソフトウェアです。

分離されたユーザーエージェントとクライアントの場合、承認コード付与は理にかなっています。たとえば、ユーザーはWebブラウザー(ユーザーエージェント)を使用して、KickstarterのFacebookアカウントでログインします。この場合、クライアントはKickstarterのサーバーの1つであり、ユーザーのログインを処理します。このサーバーは、Facebookからアクセストークンと更新トークンを取得します。したがって、このタイプのクライアントはアクセスが制限されているため「安全」であると見なされ、トークンを保存でき、Kickstarterはユーザーのリソースにアクセスでき、ユーザーの介入なしにアクセストークンを更新することもできます。

ユーザーエージェントとクライアントが結合されている場合(ネイティブのモバイルアプリケーション、JavaScriptアプリケーションなど)、暗黙の承認ワークフローが適用されます。(資格情報を入力するための)リソース所有者の存在に依存し、更新トークンをサポートしません。このクライアントがアクセストークンを保存して後で使用する場合、トークンは他のアプリケーションやクライアントのユーザーが簡単に抽出できるため、セキュリティ上の問題になります。リフレッシュトークンがないことは、このメソッドがユーザーの不在下でユーザーリソースにアクセスするために設計されていないという追加のヒントです。


2
私のブラウザは何ヶ月も私のgoogleアカウントにログインしています。では、Googleはブラウザのアクセストークンを使用するのか、有効期限の長いアクセストークンを使用するのか?有効期限が長いアクセストークンとアクセストークンの使用法の違いは何ですか?他のクライアントはアクセストークンをキャッチして、リソースの所有者がいないときにそれを使用できます。
Mohammad Nikravan 2016

有効期限の長い更新トークンアクセストークンの違いを意味すると思いますか?安全でないシナリオでは更新トークンを保存しないでください。ただし、アクセストークンは保存できます(たとえば、ブラウザーのローカルストレージに)。セキュリティは、アクセストークンの有効期間を可能な限り短くすることで達成されますが、ユーザーにとっては快適です(たとえば、x分間操作がないと自動的にログアウトできます)。寿命の長いアクセストークンを使用する場合、更新トークンは実質的に時代遅れになります。
artkoenig 2017年

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

「トークンは他のアプリケーションで簡単に抽出できます」どのように?
mvmn 2017年


60

通常の説明では、JavaScriptクライアントを使用している場合は、暗黙の付与の実装が簡単になります。しかし、これはそれを見るには間違った方法だと思います。保護されたリソースをXMLHttpRequestを介して直接要求するJavaScriptクライアントを使用している場合、安全性は低くなりますが、暗黙の付与が唯一のオプションです。

認証コードの付与によりセキュリティが強化されますが、保護されたリソースを要求するWebサーバーがある場合にのみ機能します。Webサーバーはアクセストークンを保存できるため、アクセストークンがインターネットに公開されるリスクが少なくなり、長期間続くトークンを発行できます。また、Webサーバーは信頼されているため、「更新トークン」を付与できるため、古いアクセストークンの有効期限が切れたときに新しいアクセストークンを取得できます。

ただし、これは見落としがちな点です。承認コードフローのセキュリティは、Webサーバーがユーザー認証(ログイン)で確立されたセッションで保護されている場合にのみ機能します。セッションがない場合、信頼されていないユーザーはclient_idを使用してWebサーバーにリクエストを送信するだけでよく、ユーザーがアクセストークンを持っている場合と同じです。セッションを追加すると、認証されたユーザーのみが保護されたリソースにアクセスできます。client_idは、JS Webアプリケーションの単なる「アイデンティティー」であり、Webアプリケーションの認証ではありません。

また、OAuthトークンの有効期限が切れる前にセッションを終了できることも意味します。アクセストークンを無効にする標準的な方法はありません。しかし、セッションが期限切れになると、誰もそれを知らないため、アクセストークンは役に立たなくなります。信頼できないユーザーがセッションキーにアクセスした場合、そのセッションが有効である限り、保護されたリソースにしかアクセスできません。

Webサーバーがない場合は、暗黙の付与を使用する必要があります。しかし、これはアクセストークンがインターネットに公開されることを意味します。信頼できないユーザーがアクセスした場合、有効期限が切れるまで使用できます。これは、認証コードの付与よりも長くアクセスできることを意味します。したがって、トークンの有効期限を早めることを検討し、より機密性の高いリソースへのアクセスを許可しないことをお勧めします。

* 編集:最近では、サーバーのないWebアプリでも、暗黙の付与を使用しないことをお勧めしています。代わりに、PKCEとともに、空のシークレットで構成された認証コード付与を使用できます。auth-codeの付与により、アクセストークンがブラウザの履歴に保存されるのを防ぎ、PKCEがリダイレクトURLをハイジャックして認証コードを盗んだ場合にアクセストークンを公開するのを防ぎます。この場合、クライアントがリフレッシュトークンを安全に格納できない可能性があるため、サーバーがリフレッシュトークンを返さないようにする必要があります。また、上記と同じ制限付きのアクセストークンを発行する必要があります。


21

つまり、ユーザーがブラウザーベースの、または「パブリック」(JavaScript)Webアプリをサーバー側コンポーネントなしで実行している場合、ユーザーはアプリ(およびアプリが実行されているブラウザー、場合によっては他のブラウザーも)を暗黙的に信頼します。ベースのアプリ...)。

サードパーティのリモートサーバーはなく、リソースサーバーのみです。ユーザーに代わって動作するブラウザ以外にエージェントがないため、認証コードにメリットはありません。同じ理由で、クライアントの資格情報にメリットはありません。(すべてのクライアントがこのフローの使用を試みることができます。)

ただし、セキュリティへの影響は重要です。http://tools.ietf.org/html/rfc6749#section-10.3から:

暗黙の許可タイプを使用する場合、アクセストークンはURIフラグメントで送信され、許可されていない相手に公開される可能性があります。

http://tools.ietf.org/html/rfc6749#section-10.16から:

リソース所有者は、攻撃者の悪意のあるクライアントにアクセストークンを許可することにより、リソースへのアクセスを喜んで委任する可能性があります。これは、フィッシングまたはその他の口実による可能性があります...


サーバー側コンポーネントのない「パブリック」(JavaScript)Webアプリとはどういう意味ですか?サーバーなしでWebアプリケーションを作成するにはどうすればよいですか?
ザミーページ

2
@ZammyPage、これはシングルページアプリ(SPA)と呼ばれることが多いものです。アプリ全体が静的リソースから提供されます。次に、アプリ内のJavascriptが、アクセス可能なリソースサーバー上の必要なリソースに動的にアクセスします。クライアントのコンテンツを生成するサーバーはありません。クライアントのJavaScriptは、アクセスしたリソースを表すために必要に応じてDOMを変更します。
Elroy Flynn

13

私は答えとダンのコメントを正しく理解しているのかわかりません。答えはいくつかの事実が正しいと述べているように私には思えますが、それはOPが尋ねたことを正確に指摘しています。私が正しく理解していれば、暗黙的な付与フローの主な利点は、JSアプリのようなクライアント(Chrome拡張機能など)がクライアントシークレットを公開する必要がないことです。

ダンタフリンは言った:

...認証コードフローでは、リソース所有者はアクセストークンを見る必要はありませんが、JavaScriptクライアントでは避けられません。ただし、認証コードフローを使用して、JavaScriptクライアントからクライアントシークレットを保持することはできます。

おそらく私はあなたを誤解したかもしれませんが、クライアント(この場合はJSアプリ)は、クライアントの資格情報(クライアントキーとシークレット)を認証コードフローでリソースサーバーに渡す必要がありますよね?クライアントシークレットを「JSから保持」することはできません。


6
これは古い質問ですが、これは受け入れられた質問よりも良い答えです。Implicit Grantが存在する理由は、JavaScriptクライアントが秘密を保持できないため、認証できないためです。そのため、認証サーバーは、リダイレクトuri登録とユーザーエージェントのみに依存してセキュリティを確保する必要があります。承認トークンをユーザーエージェントにのみ、特定のリダイレクトURIでのみ渡すことで、理論的には傍受を防止します(リダイレクトURIのドメインを所有していない悪意のあるユーザーは、そのURIのユーザーエージェントでコードを実行できないため)。
2016年

確かに受け入れられた答えは私を混乱させました。client_secretが何であるかを誤解していると思いました。この回答と上記のコメントは適切です。
Sarsaparilla

9

一方で暗黙的グラントは、一部のプロバイダではなく、クライアントの秘密ずに認証コードを使用して代替を実装しているクライアント側のJavaScriptアプリケーションを含むクライアントの秘密を守ることができなかったサポートのアプリに設計されました。OAuth 2.0 IETF RFC-6749は2012年に公開され、最近のいくつかの最近の議論は2017年からのものです。

IETF OAuthメーリングリストに関する2017年のディスカッションは、次の実装者から入手できます。

詳細はこちら:

インプリシットは以前はシークレットのないクライアントに推奨されていましたが、シークレットのない認証コード付与を使用することで置き換えられました。

...

以前は、ブラウザベースのアプリが「暗黙的」フローを使用することが推奨されていました。これは、アクセストークンをすぐに返し、トークン交換の手順はありません。仕様が最初に作成されて以来、業界のベストプラクティスは、認証コードフローをクライアントシークレットなしで使用することを推奨するように変更されています。これにより、stateパラメーターを使用するなど、安全なフローを作成する機会が増えます。参考資料:RedhatDeutsche TelekomSmart Health IT

Implicit Grantからのクライアントシークレットなしの認証コードへの移行は、モバイルアプリについてもここで言及されています。


あなたはこの勧告に注意したいと思います。これは、スパではなくネイティブアプリのガイダンスで推奨されていました。残念ながら、多くのオンラインディスカッション、フォーラム、さらにはoauth-wgメーリングリストに記載されているSPAに関する適切なガイダンスはありません。
トム

暗黙の許可から秘密なしで認証コードに移行することを推奨するのは、SPAとモバイルアプリの両方の推奨事項ですが、上記の私の抜粋はSPAに固有のものです。参照記事では、SPAとモバイルアプリの両方に同様のテキストを使用していますが、それぞれのテキストに「ブラウザベースのアプリ」、「モバイルアプリ、ネイティブアプリ」という言語を使用しています。また、Redhat、DT、Smart Health ITの参照はSPAに固有であり、モバイルアプリの注意事項には含まれていません。これを見つけやすくするために、回答にSPAへのディープリンクを追加しました。あなたが言及した議論へのリンクをいくつか投稿してください。
Grokify 2018

かなり最近(2018年)のoauth-wgディスカッションは、ietf.org/mail - archive/web/ oauth/ current/msg18020.htmlで見つけることができます。タイトルが「ネイティブアプリ用のOAuth 2.0」を示唆しているように、RFC 8252はネイティブアプリ用です。RedHatの、DT、スマート健康への参照は、ITは...など、メーリングリストの議論ではなく、RFCへの応答、ワーキングドラフト、ある
トム

3

他の回答に加えて、暗黙的なプロファイルでは、Authorization Serverへのコールバックを必要とするAuthorization Codeフローとは対照的に、フロントチャネルのみのフローが可能であることを認識することも重要です。これは、Auth 2.0に基づいて構築されたSSOプロトコルであるOpenID Connectで明らかになります。暗黙的なフローは、非常に人気のあるSAML POSTバインディングに似ており、承認コードフローは、あまり普及していないSAML Artifactバインディングに似ています。


3

暗黙的なフローでは、ユーザーのブラウザーが破損している場合(悪の拡張機能/ウイルス)、破損によりユーザーのリソースにアクセスし、悪意のある操作を実行できます。

認証フローでは、クライアントシークレットがわからないため、破損を防ぐことができます。


2

https://tools.ietf.org/html/rfc6749#page-8

暗黙

暗黙的な付与は、JavaScriptなどのスクリプト言語を使用してブラウザに実装されたクライアント用に最適化された、簡略化された認証コードフローです。暗黙的なフローでは、クライアントに認証コードを発行する代わりに、クライアントに直接(リソース所有者の認証の結果として)アクセストークンが発行されます。中間認証情報(認証コードなど)が発行されないため(後でアクセストークンを取得するために使用されるため)、付与タイプは暗黙的です。

暗黙的な許可フロー中にアクセストークンを発行する場合、
許可サーバーはクライアントを認証しません。一部では
場合によって、クライアントの識別情報は、リダイレクト経由で確認することができますURI
、クライアントへのアクセストークンを配信するために使用しました。アクセストークンは、リソース所有者またはリソース所有者のユーザーエージェントへのアクセス権を持つ他のアプリケーションに公開される可能性があります。

暗黙的な付与により、一部の
クライアント(ブラウザー内アプリケーションとして実装されたクライアントなど)の応答性と効率が向上し ます。これ
により、
アクセストークンを取得するために必要なラウンドトリップの数が減ります。


1

「同じ理由でクライアントの資格情報にメリットはありません。(どのクライアントもこのフローを使用しようとすることができます。)」と述べたときに、ウィルケインはこれに答えたと思います。暗黙的なフローのために、Authorization Serverから作成されます。クライアントを事前に信頼する方法がないため、ユーザーはユーザーのクレームのリリースを承認する必要があります。


1

暗黙のグラントからトークンを取得することができます認可のエンドポイント AとGET。これは、認証サーバーがCORSをサポートする必要がないことを意味します。

最近の業界のトレンドによると、それが問題ではなく、認証サーバーに関連する他の問題がないため(たとえば、何らかの理由で更新トークンがオプションではない場合)、パブリックコードクライアントでも認証コードフローが推奨されます。そして、少なくともこの(現在の)公式ドラフトのインスタンスに

歴史的には、暗黙のフローを実装する他の理由がありましたが、現在、承認コードの付与が提供するセキュリティ上の利点のほうが重要であるようです。


0

OAuth 2.0に関する記事に直面しました。著者は、暗黙的なフローの背後にある理由は、JSアプリがリクエストで非常に制限されていたためだと述べています。

なぜ暗黙のタイプがOAuth 2.0に含まれていたのか不思議に思っている場合、説明は単純です:同一生成元ポリシー。当時、フロントエンドアプリケーションは、コードを使用してアクセストークンを取得するために別のホストにリクエストを送信することはできませんでした。今日、CORS(Cross-Origin Resource Sharing)があります。

https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611

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