web-dev-qa-db-ja.com

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

ある種の盲点があるのか​​、何なのかはわかりませんが、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フラグメントのかわいいトリックがありますが、最終結果は基本的に同じです。クライアントがホストするサイトは、アクセストークンを取得できるスクリプトを含むページを提供します。

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

235
Dan Taflin

私の考えは次のとおりです。

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

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

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

183
Philip Peshin

簡単にするためではなく、セキュリティ上の理由であります

ser agentclientの違いを考慮する必要があります。

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

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

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

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

83
artkoenig

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

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

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

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

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

* EDIT:最近では、サーバーのないWebアプリでも、暗黙的許可の使用を避けることを推奨しています。代わりに、空のシークレットとPKCEで構成された認証コード付与を使用できます。 auth-codeの付与により、ブラウザーの履歴にアクセストークンが保存されるのを防ぎ、PKCEは誰かがリダイレクトURLをハイジャックして認証コードを盗む場合にそれを公開するのを避けます。この場合、クライアントはおそらくトークンを安全に保存できないため、サーバーが更新トークンを返さないようにする必要があります。また、上記と同じ制限付きでアクセストークンを発行する必要があります。

57
JW.

要約すると、ユーザーがサーバーベースのコンポーネントを使用せずにブラウザベースまたは「パブリック」(JavaScript)Webアプリを実行している場合、ユーザーは暗黙的にtrustsアプリ(および、それが実行されるブラウザ、他のブラウザベースのアプリと場合によっては...)。

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

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

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

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

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

21
Will

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

ダン・タフリンは言った:

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

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

13
tzuchien.chiu

Implicit Grant は、クライアント側のJavaScriptアプリを含むクライアントシークレットを保護できないアプリをサポートするように設計されていますが、一部のプロバイダーは、代わりにクライアントシークレットなしで認証コードを使用する代替手段を実装しています。 OAuth 2.0 IETF RFC-6749 は2012年に公開され、現在の推奨事項は最近の議論が2017年からのものです。

IETF OAuthメーリングリストに関する2017年の議論は、これらの実装者から入手できます。

詳細はこちら:

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

...

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

Implicit GrantからClient Secretを使用せずにAuthコードに移行することは、モバイルアプリでもここに記載されています。

7
Grokify

暗黙のフローでは、ユーザーのブラウザーが破損している場合(悪の拡張子/ウイルス)、破損はユーザーのリソースにアクセスし、悪いことをすることができます。

認証フローでは、クライアントシークレットを知らないため、破損することはありません。

3
Pace

他の回答に加えて、Implicitプロファイルでは、承認サーバーへのコールバックを必要とする承認コードフローではなく、フロントチャネルのみのフローが許可されることを認識することも重要です。これは、暗黙的なフローが非常に人気のあるSAML POSTバインディングに似ており、承認コードフローがあまり広く展開されていないSAMLアーティファクトバインディングに似ているAuth 2.0の上に構築されたSSOプロトコルであるOpenID Connectで明らかになります

3
Hans Z.

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

1
Mike Schwartz

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

暗黙

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

暗黙的な許可フロー中にアクセストークンを発行すると、
認可サーバーはクライアントを認証しません。いくつかで
場合、クライアントIDはリダイレクトURIを介して確認できます
アクセストークンをクライアントに配信するために使用されます。アクセストークンは、リソース所有者またはリソース所有者のユーザーエージェントにアクセスできる他のアプリケーションに公開される場合があります。

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

1
Rzv Razvan

Implicit Grantでは、GETを使用して Authorization Endpoint からトークンを取得できます。これは、承認サーバーがCORSをサポートする必要がないことを意味します。

それが懸念事項ではなく、認可サーバーに関連する他の問題が柔軟性に欠ける場合(たとえば、何らかの理由でリフレッシュトークンがオプションではない場合)、公開クライアントでも認可コードフローが優先されます 最近の業界動向 そして少なくともこれまで(現在) 公式ドラフトのインスタンス

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

  • 機密クライアント向けにバックチャネルを介してトークンを配信および使用するオプション
  • パブリッククライアントのブラウザ履歴にトークンを公開しない
  • トークンが発行される前に不正フローを中断する- PKCE で、 "すべての種類のOAuthクライアント"
0
ko la

私はちょうど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

0
Lu55