web-dev-qa-db-ja.com

RESTful Webサービス認証

Restful WebサービスAPIを持っています。これは、さまざまなサードパーティで使用されています。そのAPIの一部は制限されています(アクセスするにはユーザー名/パスワードが必要です)。認証を実装する最良の方法は何でしょうか?

私はhttpsを使用しているため、通信は暗号化されています。私には2つのアイデアがあります。

  • ユーザーが(制限付き)サービスの使用を開始する前に、POSTを使用してユーザー名/パスワードを送信します(httpsが使用されているため、資格情報は暗号化されています)。ログインが成功すると、サーバーはランダムな使い捨て値を返します(ノンス)これはこのユーザー名と一致します。次のリクエストが行われるとき、ユーザー名とともにクライアントは以前に返されたナンスを送信します。サーバーはユーザー名とノンスを照合し、リクエストされたデータとともに新しいノンスを返します。新しい各リクエストは新しいノンスを使用します。基本的に、これはダイジェストアクセス認証の軽量バージョンです。
  • このAPIはサードパーティから使用されるため、(制限された)リクエストごとにユーザー名/パスワードを使用できます。 httpsが使用されているため、暗号化されます。このアプローチの欠点は、これがRestfulに準拠しないことです(POSTは常に使用されます)。

私は最初のアプローチを選択する方がはるかに近いです(Restfulに準拠しており、比較的実装が簡単で、XML、json、またはhtmlは何も変更せずに使用できます)。あなたの意見を知りたいですか?何をお勧めしますか:最初、2番目、またはいくつかの3番目のアプローチ?

ところで、私はPython=をサーバー側で使用しています。

43
kevin

APIでこれが行われたのを見た1つの方法(および現在それを実装している方法)は、SessionというRESTfulリソースを作成し、 [〜#〜] post [〜#〜]ユーザー名とパスワードを提供します。

これが基本的に私がそれを実装した方法です:

POST /sessions { Username: "User", Password: "Password" }

時間制限付きセッションを作成し、セッションキー値と有効期限を含むセッションリソースを返します。 APIクライアントの実装の便宜のために、これをCookie値として返すこともできます。

DELETE /session/{id}

セッションをすぐに期限切れにして、使用できなくなります。これは明示的なサインアウトに使用されます。

次に、ユーザーにクエリパラメータを介してセッションキーを添付してもらいますが、Cookie値を介して送信することもできますが、両方を許可することをお勧めします。

これについて私が好むのは、それが非常に単純であるということです。

明らかに、シナリオによってセッションの管理方法が多少決まります。おそらく、セッションは時間制限がなく、無期限に持続します。また、セキュリティを強化するためにハッシュまたは暗号化されている可能性があります。

HTTPSをどこでも使用している場合は、あまり心配する必要はありません。ただし、HTTPを使用する場合は、ハッシュなどの秘密鍵とタイムスタンプを使用して、リクエストごとに安全な鍵を生成する必要があります。このようにして、HTTPSを介して秘密鍵を共有し、その後の呼び出しのためにHTTPに切り替えることができます。誰かがリクエストからキーを盗聴したとしても、ほとんどすぐに期限切れになり、役に立たなくなる可能性があります。

免責事項:私はセキュリティの専門家ではありません;-)。

22
Chris Nicola

ここでHTTP認証を使用しないだけの理由はありません。

つまり、タイムブロックナンスを取得するためのPOSTの概念はうまく機能します。しかし、そもそもなぜその余分なフープを飛び越える必要があるのか​​というのは、それが動機です。

ユーザーの検証に実際に費用がかかるため、元のパスワードにbcryptハッシュを使用する場合、この手法が考慮されました(わからない場合は、bcryptを調整して、ハッシュ関数を実行するのにかなりのリアルタイムをかけることができます)。 bcryptを介した高価な検証プロセスを通過するパスワードを使用してサービスに「ログイン」し、bcryptプロセスをバイパスする将来のリクエストと引き換えに時間ブロックトークンを取得するオプションを提供することを選択しました。 。

Bcryptプロセスの場合、HTTP認証を使用すると、サービスは通常のパスワードとトークンの両方で機能します。これにより、ユーザーはサービスのパスワードをいつでも使用できますが、コストが高くなるだけです。彼らはこれを行うことができます、彼らはすべきではありません。サービスは、クライアントが使用する認証技術を気にしません。

Nonceサービスは、スループットを向上させるための余地として提供されます。

それ以外は、標準のHTTP認証ですが、新しいスキームを使用しています。

8
Will Hartung

アマゾンウェブサービスはそれをうまくやっています、いくつかのアイデアのための方法論をチェックしてください。基本的に、クライアントはパスワードを使用して特別なhttpヘッダーを暗号化します。

ここにリンクがあります:

http://docs.aws.Amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

6
Tahbaza

サービスがブラウザーで消費されることはなく、通信はいずれにせよ暗号化されていると仮定すると、2番目の方法のバリエーションに害はありません。各要求でユーザー名/パスワードを送信するXヘッダーを追加します。例:

_GET /foo HTTP/1.1
Host: www.bar.com
X-MyUsername: foo
X-MyPassword: bar
_

別のアイデアは、HTTP基本認証を使用し、Authorization: Basic base64(user:password)- Headerを送信することです。つまり、接続が常に暗号化されている場合です。

4
tbi