質問

私は OAuth 仕様、その要件、および見つけられる実装を回避する方法を見つけようとしていますが、これまでのところ、すべてをまとめた単一のリソースを見つけるのに苦労しているため、価値以上に困難のように思えます。 。あるいは、私がほとんどのチュートリアルよりも専門的なものを探しているだけかもしれません。

既存の API のセット (一部は Java、一部は PHP) があり、それらを保護する必要があります。さまざまな理由から、OAuth が正しい方法のように思えます。残念ながら、プロバイダーを立ち上げて稼働させるのに役立つ適切なリソースを私が見つけることができないので、その理論は疑問視されています。このほとんどはシステム間の API の使用になるため、2-legged プロバイダーを実装する必要があります。それを念頭に置いて...

  1. PHP を使用して 2-legged OAuth プロバイダーを実装するための良いチュートリアルを知っている人はいますか?
  2. 2 つの言語で安全な API があることを考えると、両方の言語でプロバイダーを実装する必要がありますか、それともすべてのリクエストを集中させることができる「フロント コントローラー」としてプロバイダーを作成する方法はありますか?
  3. たとえば、PHP サービスを保護する場合、各 API に必要なプロバイダー リソースを含めて、各 API を個別に保護する必要がありますか?

ご協力いただきありがとうございます。

役に立ちましたか?

解決

一歩下がって、適切に認証されたクライアントが何を送信するのかを考えてみましょう。

両方のサービスセットからアクセスできる共通のデータベースにキーと資格情報を保存し、OAuth プロバイダーを 1 つの言語で実装するだけで済みますか?ユーザーがサービス (PHP または Java) にリクエストを送信すると、共通ストアと照合します。ユーザーが OAuth クライアントをセットアップするときは、PHP または Java アプリ (好み) を通じてそのすべてを行い、資格情報を共通 DB に保存します。

他の言語で書かれた Oauth プロバイダーがいくつかあるので、検討してみるとよいでしょう。

他のヒント

ロブ、どこからこの質問にたどり着いたのかわかりませんが、他の誰かがこの質問に遭遇した場合に備えて、私の 2 セントを追加したいと思いました。

私も数か月前に多かれ少なかれ同じ疑問を抱き、1 年の大半は「OAuth」について聞いていました。セキュリティを確保する必要がある REST API を開発していたので、OAuth について読み始めました。そして頭の中で目が後ろに回り始めました。

私はおそらく、あなたと同じように、OAuth は混乱を招くゴミだと判断し、もうやめると判断するまで、1 ~ 2 日かけて流し読みしたり読んだりしました。

そこで、一般的に API を保護する方法を調査し、その方法をよりよく理解し始めました。最も一般的な方法は、リクエストをチェックサムとともに API に送信することのようです メッセージ全体 (あなたとサーバーだけが知っている秘密でエンコードされている) は、サーバーがメッセージがクライアントから送信される途中で改ざんされたかどうかを判断するために使用できます。次のようになります。

  1. クライアントは /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad を送信します
  2. サーバーはすべてを取得し、データベースでユーザー「123」を検索し、秘密鍵をロードしてから、(クライアントが使用したのと同じ方法を使用して) 要求引数を指定して自身のチェックサムを再計算します。
  3. サーバーが生成したチェックサムとクライアントが送信したチェックサムが一致する場合、リクエストは OK として実行されます。一致しない場合は、改ざんされていると見なされ、拒否されます。

チェックサムは HMAC と呼ばれ、これの良い例が必要な場合は、アマゾン ウェブ サービスが使用するものです (ただし、引数を「チェックサム」ではなく「署名」と呼びます)。

したがって、これが機能するための重要なコンポーネントの 1 つは、クライアントとサーバーが同じ方法で HMAC を生成する必要があること (そうしないと一致しない) であることを考えると、すべての引数を組み合わせる方法に関するルールが必要です。 。それから突然、OAuth の「パラメータの自然なバイト順序」のくだらないことをすべて理解しました...必要なため、署名を生成する方法のルールを定義しているだけです。

もう 1 つのポイントは、HMAC 生成に含めるすべてのパラメータは、リクエストの送信時に改ざんできない値であることです。

したがって、URI ステムを署名としてエンコードするだけの場合は、たとえば次のようになります。

  • /user.json == askJdla9/kjdas+Askj2l8add

この場合、メッセージ内で改ざんできないのは URI だけです。引数はサーバーが再計算する「チェックサム」値の一部ではないため、すべての引数が改ざんされる可能性があります。

あるいは、計算にすべてのパラメータを含めたとしても、悪意のある仲介者や盗聴者が API 呼び出しを傍受し、それをサーバーに何度も再送信し続ける「リプレイ攻撃」のリスクが依然としてあります。

この問題は、HMAC 計算にタイムスタンプ (常に UTC を使用) を追加することで修正できます。

リマインダー:サーバーは同じ HMAC を計算する必要があるため、秘密キー (OAuth では Consumer_secret と呼んでいると思います) を除く、計算で使用する値を送信する必要があります。したがって、タイムスタンプを追加する場合は、リクエストと一緒にタイムスタンプ パラメータを送信してください。

API をリプレイ攻撃から保護したい場合は、nonce 値を使用できます (これは、サーバーが生成してクライアントに与える 1 回限りの使用値で、クライアントはそれを HMAC で使用し、リクエストを送り返し、サーバーは確認して、その nonce 値を DB 内で「使用済み」としてマークし、別のリクエストでその nonce 値を再度使用することはありません)。

注記:「nonce」は、「リプレイ攻撃」問題を解決するための非常に正確な方法です。タイムスタンプは優れていますが、コンピューターが常に同期したタイムスタンプ値を持っているとは限らないため、サーバー側でどのように処理するかを許容できるウィンドウを許可する必要があります。 old」というリクエストが考えられます (10 分、30 分、1 時間など)。Amazon では、承認または拒否するまでに 15 分を要します。このシナリオでは、API は時間枠全体にわたって技術的に脆弱です。

nonce 値は素晴らしいと思いますが、整合性を維持することが重要な API でのみ使用する必要があります。私の API ではこれは必要ありませんでしたが、ユーザーが要求した場合に後で追加するのは簡単です...文字通り、DB に「nonce」テーブルを追加し、次のような新しい API をクライアントに公開するだけです。

  • /nonce.json

そして、HMAC 計算でそれを私に送り返すとき、DB をチェックして、それが以前に使用されていないことを確認し、一度使用された場合は、DB 内でそのようにマークして、リクエストが再び来た場合に備えて、同じように私はそれを拒否します。

まとめ

とにかく、長い話を手短に言うと、私が今説明したことはすべてです 基本的に これは「2-legged OAuth」として知られています。クライアントを承認するために当局 (Twitter、Facebook、Google など) に流れる追加のステップはなく、そのステップは削除され、代わりに、送信している HMAC が一致する場合、サーバーは暗黙的にクライアントを信頼します。つまり、クライアントは正しい Secret_key を持っており、それを使用してメッセージに署名しているため、サーバーはそれを信頼します。

オンラインで調べてみると、現在 API メソッドを保護するためにこれが好まれている方法のようです。Amazon は、HMAC を生成するために全体に署名する前に、パラメーターにわずかに異なる組み合わせ方法を使用することを除いて、この方法をほぼ正確に使用しています。

興味があれば私は この旅全体を書き上げた そして私がそれを学んでいるときの思考プロセス。これは、このプロセスのガイド付き思考ツアーを提供するのに役立つかもしれません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top