OAuth 2.0:利点と使用例—なぜですか?


256

誰もがOAuth2の何が良いのか、なぜそれを実装する必要があるのか​​説明できますか?私はそれについて少し混乱しているので私は尋ねます—これが私の現在の考えです:

OAuth1(より正確にはHMAC)リクエストは論理的で、理解しやすく、開発しやすく、本当に安全です。

代わりに、OAuth2は認証リクエスト、アクセストークン、リフレッシュトークンをもたらします。セッションの開始時に3つのリクエストを作成して、必要なデータを取得する必要があります。それでも、トークンの有効期限が切れると、いずれかのリクエストが最終的に失敗します。

また、別のアクセストークンを取得するには、アクセストークンと同時に渡された更新トークンを使用します。それはセキュリティの観点からアクセストークンを無駄にしますか?

さらに、/ r / netsecが最近示したように、SSLはすべて完全に安全なわけではないため、安全なHMACの代わりにすべてをTLS / SSLに取得しようとすると、混乱します。

OAuthは、100%の安全性ではないと主張していますが、公開して完成させています。これは、プロバイダーの観点からは、有望とは言えません。ドラフトが6つの異なるフローに言及しているときに、ドラフトが何を達成しようとしているのかを確認できますが、それは私の頭の中ではうまくいきません。

実際にそれを嫌うよりも、その利点と理由を理解するのが私の苦労かもしれないと思うので、これは少し不当な攻撃かもしれません、そしてこれが暴言のように思えるかもしれません。


回答:


324

背景:OAuth 1.0aおよび2.0のクライアントおよびサーバースタックを作成しました。

OAuth 1.0aと2.0はどちらも、サーバーがユーザーのIDを保証する2レッグ認証と、サーバーがユーザーのID のコンテンツプロバイダーによって保証される3 レッグ認証をサポートしています。Three-legged認証では、承認リクエストとアクセストークンが関係します。OAuth1にもそれらがあることに注意することが重要です。

複雑なもの:三脚認証

OAuth仕様の主なポイントは、コンテンツプロバイダー(Facebook、Twitterなど)がサーバー(たとえば、クライアントに代わってコンテンツプロバイダーと通信することを望むWebアプリ)に、クライアントが何らかのIDを持っていることを保証することです。 。Three-Legged認証が提供するのは、クライアントまたはサーバーがそのIDの詳細(ユーザー名やパスワードなど)を知る必要がなくてもそれを実行できる機能です。

OAuthの詳細に深く入り込まない(?):

  1. クライアントはサーバーに承認要求を送信し、サーバーがクライアントがそのサービスの正当なクライアントであることを検証します。
  2. サーバーはクライアントをコンテンツプロバイダーにリダイレクトして、そのリソースへのアクセスを要求します。
  3. コンテンツプロバイダーはユーザーのIDを検証し、多くの場合、リソースへのアクセス許可を要求します。
  4. コンテンツプロバイダーは、クライアントをサーバーにリダイレクトし、成功または失敗を通知します。このリクエストには、成功時の認証コードが含まれています。
  5. サーバーは、コンテンツプロバイダーに帯域外要求を行い、認証コードをアクセストークンと交換します。

サーバーは、アクセストークンを渡すことにより、ユーザーに代わってコンテンツプロバイダーにリクエストを送信できます。

各交換(クライアント->サーバー、サーバー->コンテンツプロバイダー)には共有シークレットの検証が含まれますが、OAuth 1は暗号化されていない接続で実行できるため、各検証はシークレットをネットワーク経由で渡すことができません。

お気づきのとおり、これはHMACで行われます。クライアントは、サーバーと共有するシークレットを使用して、認証リクエストの引数に署名します。サーバーは引数を受け取り、クライアントのキーを使用して自身に署名し、それが正当なクライアントであるかどうかを確認できます(上記のステップ1)。

この署名では、クライアントとサーバーの両方が引数の順序に同意する必要があるため(これらはまったく同じ文字列に署名します)、OAuth 1に関する主な不満の1つは、サーバーとクライアントの両方でソートと同じように署名します。これは厄介なコードであり、それが正しいか401 Unauthorized、ほとんど助けを借りずに取得できます。これにより、クライアントを作成する際の障壁が高まります。

OAuth 2.0は、SSLを介して実行する認証リクエストを要求することで、引数の並べ替えや署名の必要性を完全に排除します。クライアントはその秘密をサーバーに渡し、サーバーはそれを直接検証します。

同じ要件がサーバー->コンテンツプロバイダー接続にも存在します。これはSSLであるため、OAuthサービスにアクセスするサーバーの作成に対する1つの障壁が取り除かれます。

これにより、上記のステップ1、2、および5の処理が非常に簡単になります。

したがって、この時点で、サーバーには永続的なアクセストークンがあり、これはユーザーと同等のユーザー名/パスワードです。アクセストークンをリクエストの一部として(クエリ引数、HTTPヘッダー、またはPOSTフォームデータとして)渡すことにより、ユーザーに代わってコンテンツプロバイダーにリクエストを送信できます。

コンテンツサービスがSSL経由でのみアクセスされる場合は、これで完了です。プレーンなHTTPを介して利用できる場合、その永続的なアクセストークンを何らかの方法で保護したいと考えています。接続をスニッフィングすると、誰でもユーザーのコンテンツに永久にアクセスできるようになります。

OAuth 2で解決される方法は、更新トークンを使用することです。更新トークンは永続的なパスワードと同等になり、SSL経由でのみ送信されます。サーバーがコンテンツサービスにアクセスする必要がある場合、サーバーは更新トークンを短期間のアクセストークンと交換します。このようにして、すべてのスニファ可能なHTTPアクセスは、期限切れになるトークンを使用して行われます。GoogleはOAuth 2 APIで5分の有効期限を使用しています。

したがって、更新トークンを除いて、OAuth 2はクライアント、サーバー、コンテンツプロバイダー間のすべての通信を簡素化します。また、更新トークンは、コンテンツが暗号化されていない状態でアクセスされているときにセキュリティを提供するためにのみ存在します。

Two-legged認証

ただし、サーバーが独自のコンテンツへのアクセスを制御するだけでよい場合もあります。Two-legged認証により、クライアントはサーバーでユーザーを直接認証できます。

OAuth 2は、広く使用されていたOAuth 1の一部の拡張機能を標準化します。私が最もよく知っているのはTwitterによってxAuthとして紹介されたものです。OAuth 2では、リソース所有者のパスワード認証情報として確認できます。

基本的に、ユーザーの資格情報(ユーザー名とパスワード)でクライアントを信頼できる場合、クライアントはそれらをコンテンツプロバイダーと直接交換してアクセストークンを取得できます。これにより、モバイルアプリでのOAuthがより便利になります。3脚認証では、コンテンツサーバーでの承認プロセスを処理するために、HTTPビューを埋め込む必要があります。

OAuth 1では、これは公式の標準の一部ではなく、他のすべての要求と同じ署名手順が必要でした。

リソースオーナーパスワード認証情報を使用してOAuth 2のサーバー側を実装しました。クライアントの観点から見ると、アクセストークンの取得は簡単になりました。サーバーからアクセストークンをリクエストし、クライアントID /シークレットをHTTP Authorizationヘッダーとフォームデータとしてのユーザーのログイン/パスワード。

利点:シンプルさ

したがって、実装者の観点から見ると、OAuth 2に見られる主な利点は、複雑さが軽減されていることです。要求の署名手順は必要ありません。これは厳密には難しいことではありませんが、確かに手間がかかります。これにより、サービスのクライアントとして機能するために必要な作業が大幅に削減されます。これは、(現代のモバイルの世界では)痛みを最小限に抑えたい場所です。サーバー->コンテンツプロバイダー側​​の複雑さが緩和されることで、データセンターでのスケーラビリティが向上します。

そして、現在広く使用されているOAuth 1.0a(xAuthなど)のいくつかの拡張を標準化します。


20
用語について:不明確なもの(クライアント、サーバー、ユーザー..)を使用するのではなく、影響を受ける関係者(承認サーバー、リソースサーバー、リソース所有者)の正式名に固執するほうがよいでしょう。
Aydin K.

こんにちはピーターは、Aydin Kが言うように、承認サーバー、リソースサーバー、リソースオーナー、クライアント、サーバー、ユーザーの代わりに投稿を変更できます。それは主に南の初心者のために役立ちます。ありがとうございました。
JustCode

@Aydin Kは、クライアント、サーバー、ユーザーに代わって、承認サーバー、リソースサーバー、リソース所有者の比較についてコメントできます。私はオースにとっても新しい人なので。
JustCode

誰かがoauthを理解していない場合。プレーンな英語ではなく、oauthの用語を使用してoauthを説明することは、生産的ではないようです。
ジェイコブ

7

まず、OAuth認証で明確に示されているように

OAuth 2.0は認証プロトコルではありません。

アプリケーションにアクセスするユーザーのコンテキストでの認証は、現在のユーザーが誰であるか、およびそれらが存在するかどうかをアプリケーションに通知します。完全な認証プロトコルは、一意の識別子、電子メールアドレス、アプリケーションが「おはよう」と言ったときに何を呼び出すかなど、おそらくこのユーザーに関するいくつかの属性も通知します。

ただし、OAuthはアプリケーションにそれを伝えません。OAuthはユーザーについてまったく何も述べていません。また、ユーザーが自分の存在を証明した方法や、ユーザーがまだそこにいる場合でも、それについては触れていません。OAuthクライアントに関する限り、クライアントはトークンを要求し、トークンを取得し、最終的にそのトークンを使用していくつかのAPIにアクセスしました。誰がアプリケーションを承認したのか、あるいはそこにユーザーがいたかどうかについては何も知りません。

OAuth2と互換性のあるOAuthを使用したユーザー認証の標準:OpenID Connectがあります。

OpenID Connect IDトークンは、署名されたJSON Web Token(JWT)であり、通常のOAuthアクセストークンと共にクライアントアプリケーションに渡されます。IDトークンには、ユーザー(サブ)の識別子、トークンを発行したIDプロバイダーの識別子(iss)、およびこのトークンが作成されたクライアントの識別子( aud)。

Goでは、coreos / dex、OpenID Connect Identity(OIDC)、およびプラグイン可能なコネクターを備えたOAuth 2.0プロバイダーを確認できます。

この投稿からの回答vonc


それで、自分のクライアント以外に追加のクライアントがないアプリケーションを構築している場合、OAuthの実装が推奨されますか?または、OAuthを完全に回避して、直接HTTP基本認証を使用する方が良いでしょうか?
CristianHG

3

この質問への回答は少し異なりますが、主に@Peter Tがすべて回答したため、非常に正確で簡潔になります。

この標準から私が見る主な利点は、2つの原則を尊重することです。

  1. 関心事の分離。
  2. 通常はビジネスに役立つWebアプリケーションから認証を分離する。

そうすることによって、

  1. シングルサインオンの代替手段を実装できます。1つのSTSを信頼するアプリケーションが複数ある場合。つまり、すべてのアプリケーションに対して1つのユーザー名。
  2. Webアプリケーション(クライアント)がユーザーに属し、Webアプリケーション(クライアント)に属していないリソースにアクセスできるようにすることができます。
  3. 認証プロセスを信頼できるサードパーティに委任でき、ユーザー認証の検証について心配する必要はありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.