web-dev-qa-db-ja.com

OAuth2のリソース所有者パスワード資格情報付与タイプを使用しながら、クライアント資格情報を機密に保つ方法

休憩サービスを構築しており、認証にOAauth 2を使用します。 現在のドラフト (5月19日のv2-16)は 4つの付与タイプ を説明しています。これらは、承認(アクセストークン)を取得するためのメカニズムまたはフローです。

  1. 認証コード
  2. 暗黙のグラント
  3. リソース所有者の資格情報
  4. クライアント資格情報

目的が異なるため、これら4つすべてをサポートする必要があるようです。最初の2つ(場合によっては最後の1つ)は、APIへのアクセスが必要なサードパーティアプリから使用できます。承認コードは、安全なサーバーに常駐する幸運なWebアプリケーションを承認する標準的な方法です。一方、暗黙的な許可フローは、資格情報を極秘に保つことができないクライアントアプリケーション(モバイル/デスクトップなど)アプリケーション、JavaScriptクライアントなど)。
3番目のメカニズムを使用して、モバイルデバイスでのユーザーエクスペリエンスを改善します。ユーザーをWebブラウザーなどのログインダイアログに移動する代わりに、ユーザーは単にユーザー名を入力し、アプリケーションで直接パスワードを入力してログインします。また、クライアント資格情報付与タイプを使用して、どのユーザーにも関連付けられていないパブリックデータの表示に使用できるアクセストークンを取得します。この場合、これはそれほど多くの承認ではなく、登録済みのアプリケーションにのみアクセスを許可するAPIキーに似たものであり、必要に応じてアクセスを取り消すオプションを提供します。

だから私の質問は:

  1. さまざまな助成金タイプの目的を正しく理解したと思いますか?
  2. クライアント資格情報をどのように機密に保つことができますか? 3番目と4番目の両方のケースでは、クライアントIDとクライアントシークレットをクライアント上のどこかに置く必要がありますが、これは良い考えではありません。
  3. 暗黙的な付与タイプを使用し、クライアントシークレットを公開しない場合でも、同じ承認メカニズムとクライアントIDを使用して別のアプリケーションがアプリになりすますのを防ぐにはどうすればよいですか?

要約すると、クライアントアプリケーションからのクライアント資格情報とリソース所有者の資格情報フローを使用できるようになります。これらの両方のフローでは、何らかの方法でクライアントシークレットを保存する必要がありますが、クライアントはモバイルアプリケーションまたはJavaScriptアプリケーションであるため、これらは簡単に盗まれます。

74
Georgi Stoyanov

私は同様の問題に直面していますが、OAuthは比較的新しいものです。公式モバイルアプリが使用するAPIに「リソース所有者のパスワード認証情報」を実装しました。ウェブフローは、モバイルプラットフォームで使用するのは非常に恐ろしく、ユーザーがアプリをインストールして信頼すると公式アプリであるため、ユーザーはアプリに直接ユーザー名/パスワードを入力するのが快適だと感じるはずです。

問題は、指摘したように、APIサーバーがアプリのclient_idを安全に検証する方法がないことです。 client_secretをアプ​​リのコード/パッケージに含めると、アプリをインストールするすべてのユーザーに公開されるため、client_secretを要求してもプロセスの安全性は向上しません。したがって、基本的に、他のアプリはclient_idをコピーすることで自分のアプリになりすますことができます。

各ポイントで回答を送信するだけです:

  1. 仕様のさまざまなドラフトを読み直して、何か変更があったかどうかを確認し、主にリソース所有者のパスワード資格情報セクションに焦点を当てていますが、これらは正しいと思います。クライアント資格情報(4)分析やすべてのユーザーに情報を取得する必要がある場合など、単なる「公開」情報以上にアクセスする必要がある社内サービスまたはサードパーティサービスでも使用できると思います。

  2. 私はあなたがクライアント上で何も秘密にしておくことはできないと思います。

  3. 他の誰かがあなたのクライアントIDを使用することを止めるものは何もありません。これも私の問題です。コードがサーバーを離れて、アプリとしてインストールされるか、ブラウザーでJavascriptとして実行されると、何も秘密であると想定することはできません。

私たちのウェブサイトでは、クライアント資格情報フローで説明したものと同様の問題がありました。私がやったことは、認証をサーバー側に移動することです。ユーザーはWebアプリを使用して認証できますが、APIへのOAuthトークンはサーバー側に保存され、ユーザーのWebセッションに関連付けられます。Javascriptコードが行うすべてのAPIリクエストは実際にAJAX Webサーバーへの呼び出し。ブラウザはAPIで直接認証されず、代わりに認証されたWebセッションを持ちます。

クライアントクレデンシャルのユースケースは異なるようです。サードパーティのアプリについて話しているだけで、この方法でのみパブリックデータを提供しています。あなたの懸念は有効だと思います(誰でも盗んで他の人のAPIキーを使用できます)が、APIキーを取得するために無料の登録のみが必要な場合、なぜ誰かが本当にキーを盗もうとするのかわかりません。

各APIキーの使用状況を監視/分析して不正使用の検出を試みることができます。その時点で、1つのAPIキーを無効にし、正当なユーザーに新しいキーを与えることができます。これが最良のオプションかもしれませんが、決して安全ではありません。

これを少し厳しくロックしたい場合は、リフレッシュトークンのようなスキームを使用することもできますが、実際にどれだけの利益が得られるかはわかりません。 Javascriptに公開されたAPIトークンを1日に1回期限切れにし、サードパーティが(秘密の)更新トークンを使用して何らかのサーバー側の更新を行う必要がある場合、盗まれたAPIトークンは1日以上有効ではありません。トークン泥棒になる可能性がある人は、代わりに登録することをお勧めします。しかし、他のすべての人にとってはある種の苦痛なので、これがそれだけの価値があるかどうかはわかりません。

55
heavi5ide