1. ホーム
  2. oauth

[解決済み】OAuth2.メリットとユースケース - なぜ?

2022-03-31 23:12:49

質問

OAuth2の何が良いのか、なぜそれを実装する必要があるのか、どなたか説明してください。私はこのことについて少し混乱しているので質問します。

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

OAuth2では、認証リクエスト、アクセストークン、リフレッシュトークンが登場し、目的のデータを取得するために、セッション開始時に3回のリクエストを行う必要があります。さらに、トークンの有効期限が切れると、最終的にリクエストの1つが失敗してしまいます。

また、アクセストークンを取得するためには、アクセストークンと同時に渡されたリフレッシュトークンを使用するんですね。これでは、セキュリティの観点からアクセストークンが無駄になってしまうのでは?

さらに、/r/netsecが最近示したように、SSLはすべて完全に安全というわけではないので、安全なHMACではなく、すべてをTLS/SSLに移行しようとする動きは私を困惑させます。

OAuthは、100%の安全性ではなく、公開と終了を目指すと主張しています。プロバイダーの立場からすると、それは必ずしも期待できるものではありません。6つの異なるフローについて言及している時点で、この草案が何を達成しようとしているかはわかりますが、私の頭の中ではうまくまとまりません。

このように、「嫌い」というよりも、「メリット」や「理由」を理解するのに苦労しているのかもしれないので、ちょっと謂れのない攻撃かもしれませんし、暴言のように思われたら申し訳ありません。

どのように解決するのか?

背景 OAuth 1.0a と 2.0 のクライアントとサーバーのスタックを書きました。

OAuth 1.0a & 2.0の両方がサポートされています。 二足歩行認証 サーバーがユーザーの身元を保証するもので、かつ 3本足認証 サーバは、コンテンツプロバイダからユーザの身元を保証される。三脚認証は、認可要求とアクセストークンが登場するところですが、OAuth 1にはそれらもあることに留意することが重要です。

複雑なもの:3本足認証

OAuth仕様の主なポイントは コンテンツプロバイダ (Facebook、Twitterなど)は サーバー (例えば、クライアントに代わってコンテンツ・プロバイダーと話をしたいウェブ・アプリ)は、クライアントが何らかのアイデンティティを持っていることを確認します。3本足認証が提供するのは、クライアントやサーバに依存しない機能です。 そのIDの詳細を知る必要はない (例:ユーザー名とパスワード)。

OAuthの詳細に深入りすることなく(?

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

アクセストークンを渡すことで、サーバーはユーザーの代わりにコンテンツプロバイダーへのリクエストを行うことができるようになります。

各交換(クライアント->サーバ、サーバ->コンテンツプロバイダ)には共有秘密の検証が含まれますが、OAuth 1は暗号化されていない接続で実行できるため、各検証で秘密は伝えられません。

それは、ご指摘の通り、HMACで実現しています。クライアントはサーバと共有する秘密を使って、認証リクエストの引数に署名します。サーバはその引数を受け取り、クライアントの鍵で署名し、 (上記のステップ1で) 正規のクライアントであるかどうかを確認することができるのです。

この署名では、クライアントとサーバーの両方が引数の順序に同意する必要があります (つまり、まったく同じ文字列に署名することになります)。OAuth 1 に対する主な不満のひとつは、サーバーとクライアントの両方が同じように並び替えて署名する必要があることです。これは面倒なコードで、正しいか、あるいは 401 Unauthorized をほとんど使わずに そのため、クライアントを書くための障壁が高くなります。

認証要求がSSL上で実行されることを要求することで、OAuth 2.0は引数のソートや署名の必要性を完全に排除しているのです。クライアントはサーバにその秘密を渡し、サーバはそれを直接検証します。

サーバーとコンテンツプロバイダーの接続も同じ要件で、SSLなので、OAuthサービスにアクセスするサーバーを書くための障壁が一つ取り除かれました。

そのため、上記のステップ1、2、5では、かなり楽になります。

この時点で、私たちのサーバーは、ユーザー名とパスワードに相当する永久アクセストークンを持っています。このアクセストークンをリクエストの一部として(クエリー引数、HTTPヘッダー、またはPOSTフォームデータとして)渡すことで、ユーザーの代わりにコンテンツプロバイダーにリクエストを行うことができます。

コンテンツ・サービスがSSL経由でのみアクセスできる場合は、これで完了です。もしプレーンなHTTPで利用できるのであれば、その恒久的なアクセストークンを何らかの方法で保護したいと思います。接続を盗聴されると、ユーザーのコンテンツに永久にアクセスできてしまうからです。

OAuth 2でそれを解決する方法は リフレッシュトークン . リフレッシュトークンは永久パスワードに相当するものになり、それは のみSSLで送信されます。 . サーバーはコンテンツサービスにアクセスする必要があるとき、リフレッシュトークンを短命のアクセストークンに交換します。このようにして、すべての盗聴可能なHTTPアクセスは、有効期限が切れたトークンで行われます。Googleは、OAuth 2 APIで5分間の有効期限を使用しています。

つまり、リフレッシュ・トークンを除けば、OAuth 2 はクライアント、サーバー、コンテンツ・プロバイダ間のすべての通信を簡素化するものです。そして、リフレッシュ・トークンは、コンテンツが暗号化されていない状態でアクセスされた場合にセキュリティを確保するためにのみ存在します。

2本足認証

しかし、時には、サーバーが自分自身のコンテンツへのアクセスを制御するだけでよい場合もあります。2脚認証は、クライアントがサーバと直接ユーザを認証することを可能にします。

OAuth 2 は、OAuth 1 で広く使われていたいくつかの拡張を標準化したものです。私が最もよく知るものは、Twitter が導入した xAuth . OAuth 2 では、次のように表示されます。 リソース所有者のパスワード認証情報 .

基本的に、ユーザーの認証情報(ユーザー名とパスワード)をクライアントが信頼できれば、コンテンツ・プロバイダとアクセストークンを直接交換することができます。三脚認証では、コンテンツサーバーとの認証処理を行うためにHTTPビューを埋め込まなければなりません。

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

OAuth 2のサーバーサイドにResource Owner Password Credentialsを実装したところ、クライアントから見ると、HTTP AuthorizationヘッダーにクライアントID/secretを、フォームデータにユーザーのログイン/パスワードを渡して、アクセストークンをサーバーに要求する、というシンプルなものになりました。

メリット シンプルさ

実装者の視点から見ると、OAuth 2の主な利点は、複雑さが軽減されることです。リクエストの署名手続きが不要になります。これは決して難しいことではありませんが、確かに面倒です。これは、サービスのクライアントとして行動するために必要な作業を大幅に削減するもので、(現代のモバイルの世界では)最も痛みを最小限に抑えたいところです。サーバーとコンテンツプロバイダー側の複雑さが軽減されたことで、データセンターでのスケーラビリティも向上しています。

また、現在広く使われている OAuth 1.0a の拡張機能 (xAuth など) を標準に成文化したものです。