web-dev-qa-db-ja.com

ステートレス(セッションレス)&クッキーレス認証を行う方法は?

ボブは、何かを達成するためにWebアプリケーションを使用します。そして:

  • 彼のブラウザはダイエット中のため、cookiesをサポートしていません。
  • Webアプリケーションは人気があり、特定の瞬間に多くのユーザーに対処します-scaleをうまくやらなければなりません。セッションを維持することで同時接続数の制限が課せられ、もちろん、無視できないパフォーマンスペナルティがもたらされる限り、セッションレスシステム:)

重要な注意事項:

  • transport securityHTTPSとその親友);
  • カーテンの後ろで、Webアプリケーションは多くの操作を外部サービスに、現在はユーザーの代わりにに委任します(これらのシステムはBobをユーザーの1人として認識します)-これはつまりボブの資格情報を転送する必要があります

さて、ボブをどのように認証しますか(すべてのリクエストで)?そのようなことを実装するための合理的な方法はどれでしょうか?

  • tennisHTMLフォームの非表示フィールド ... theballには資格情報(ユーザー名とパスワード)が含まれ、2つのラケットはブラウザとそれぞれウェブアプリケーション。つまり、Cookieではなくフォームフィールドを介してデータをやり取りする場合があります。 Web要求ごとに、ブラウザーは資格情報をポストします。ただし、単一ページのアプリケーションの場合、これはゴムの壁に対してsquashを再生するように見えるかもしれませんtennisを再生します。資格情報を含むwebフォームが存続する可能性があるためウェブページの全ライフタイム(そしてサーバーは認証情報を返さないように設定されます)。
  • ユーザー名とパスワードをページのコンテキストに保存する-JavaScript変数など。ここにはシングルページが必要です、私見。
  • 暗号化されたトークン-ベースの認証。この場合、ログインアクションにより、暗号化されたセキュリティトークンが生成されます(ユーザー名+パスワード+その他)。このトークンはクライアントに提供され、今後のリクエストにはトークンが添付されます。これは理にかなっていますか?すでにHTTPSを使用しています...
  • その他...
  • 最後の手段:これを行わないで、セッションに資格情報を保存してください!セッションは良いです。クッキーの有無にかかわらず。

これまでに説明したアイデアのいずれかに関して、Web /セキュリティ上の懸念がありますか?例えば、

  • time-outing-資格情報とともにtimestampを保持できます(time-stamp = Bobが資格情報を入力した時間)。例えば。 NOW-タイムスタンプ>しきい値の場合、リクエストを拒否する可能性があります。
  • クロスサイトスクリプティング保護-なんら違いはないはずですよね?

これを読むのに時間を割いてくれてありがとう:)

105
turdus-merula

ああ、これらの質問が大好きです。セッションなしでセッションを維持します。

私は、アプリケーション評価時のスティントでこれを行うための複数の方法を見てきました。人気のある方法の1つは、テニスをするで説明した方法です。ユーザーを認証するために、すべてのリクエストでユーザー名とパスワードを送信します。私の意見では、これは、特にアプリケーションが単一ページでない場合、安全ではありません。また、将来的に認証に加えてアプリに承認を追加する場合は特にスケーラブルではありません(ただし、ログインに基づいて何かを構築できると思います)

人気のある、完全にステートレスなメカニズムではありません(JavaScriptを実行していると仮定した場合)は、セッションCookieをJavaScriptに埋め込むことです。私のセキュリティ担当者はこれを叫んでいますが、実際には機能します-すべてのリクエストにはX-Authentication-Tokenヘッダーまたはそのようなものがあり、バックエンドでデータベース、メモリ内のファイルストアなどにマッピングしますユーザーを検証します。このトークンには、指定した時間のタイムアウトを設定できます。タイムアウトした場合、ユーザーは再度ログインする必要があります。それはかなりスケーラブルです-データベースに保存し、その1つのSQLステートメントを実行し、正しいインデックスを使用すると、複数の同時ユーザーであっても、実行にかかる時間はほとんどありません。ただし、ここでの負荷テストは間違いなく役立ちます。質問を正しく読んだ場合、これは暗号化されたトークンメカニズムです-ただし、ユーザー名+パスワード+その他の組み合わせを使用するのではなく、32文字の暗号的にランダムなトークンを使用することを強くお勧めします-この方法では、予測不能ですが、それでもユーザーIDなどに関連付けることができます。

どちらを使用しても、安全に送信されるようにしてください。 HTTPSはネットワーク全体を保護しますが、URLを介してセッショントークン(または、さらに悪いことに、URLを介した資格情報)をリークした場合は保護しません。ヘッダーを使用することをお勧めします。それが不可能な場合は、毎回POSTリクエストを介してトークンを送信します(これはユーザーのブラウザーの非表示フォームフィールドを意味します。)POSTリクエストでは、念のためCSRF防御を使用する必要がありますが、トークン自体を使用することは何らかのCSRF防御である可能性があります。

最後に、重要なことですが、バックエンドに期限切れのトークンをパージするメカニズムがあることを確認してください。これは過去の多くのアプリケーションの悩みの種でした-急速に成長している認証トークンのデータベースは決して消えないようです。複数のユーザーログインをサポートする必要がある場合は、数を制限するか、各トークンの時間制限を短くしてください。前にも言ったように、負荷テストがこれに対する答えかもしれません。

私が考えることができるいくつかの他のセキュリティの懸念がありますが、それらはこの段階で対処するには広すぎます-すべての使用(および悪用)ケースを念頭に置いて、おそらくかなり良い実装を行うことができるはずですこのシステム。

73

ログインオプションについて-通常、ゲストのセッションもサポートしたいと思います。

したがって、ログインを強制する場合は、暗号化されたトークンオプションが適している可能性があります。なんとなくゲストセッションにもいいかもしれません。別の方向では、URLにトークンを追加することとテニスオプションを組み合わせることがあります。

URLでのみ資格情報を送信すると危険な場合があることに注意してください。たとえば、HTTPリファラーヘッダーを介してトークンをリークしたり、トラフィックを検査したり、コンピューターを監視したりすることによってトークンをリークする場合があります。

もう1つ、Cookieを使用できたとしても、クロスサイトリクエストフォージェリ(CSRF)攻撃から身を守るために、ランダムトークンまたはランダムベリファーを追加することをお勧めします。

1
Gari BN