1. ホーム
  2. security

[解決済み] ステートレス(セッションレス)・クッキーレス認証を行うには?

2022-08-23 06:30:11

質問

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

  • 彼のブラウザはダイエット中であり、そのため クッキー .
  • ウェブアプリケーションは人気のあるもので、ある瞬間に多くのユーザーを扱います。 規模 でなければなりません。セッションを維持する限りは 同時接続数に制限がある限り そしてもちろん、無視できない数の パフォーマンス・ペナルティ であるならば、私たちはセッションレスシステムを持ちたいかもしれません :)

いくつかの重要な注意事項があります。

  • 私たちは トランスポートセキュリティ ( HTTPS とその親友たち)。
  • カーテンの裏側では、ウェブアプリケーションは多くの操作を 外部サービス に、現在の ユーザーに代わって (これらのシステムはボブをユーザの一人として認識しています) - これはつまり 私たちは彼らにボブの認証情報を転送しなければなりません。 .

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

  • 遊び テニス を経由して資格証明書と HTML フォームの隠しフィールド ... ボール にはクレデンシャル( ユーザー名 & パスワード ) と 2つのラケット はそれぞれブラウザとウェブアプリケーションです。言い換えれば、クッキーを介する代わりに、フォームフィールドを介してデータをやり取りすることもあります。各ウェブリクエストで、ブラウザはクレデンシャルを投稿します。ただし シングルページアプリケーション を再生しているように見えるかもしれません。 スカッシュ をするのではなく、ゴムの壁に向かって テニス のように ウェブフォーム の寿命が尽きるまで生き続けるかもしれません。 ウェブページ (そして、サーバーはクレデンシャルを返さないように設定されます)。
  • ユーザー名とパスワードをページのコンテキストに格納する - JavaScript変数など。IMHO では、ここでは単一ページが必要です。
  • 暗号化されたトークンに基づく認証。この場合、ログインアクションは、暗号化されたセキュリティトークン(ユーザー名+パスワード+何か他のもの)を生成することになります。このトークンはクライアントに返され、次のリクエストはトークンを伴います。これって意味があるのでしょうか?私たちはすでに HTTPS を持っているのですから...。
  • その他...
  • 最後の手段: こんなことしないで、クレデンシャルをセッションに保存してください! セッションは良いものです。クッキーの有無にかかわらず。

前に説明したアイデアのいずれかについて、Web/セキュリティに関する懸念が思い浮かびますか?たとえば

  • タイムアウト - を維持することがあります。 タイムスタンプ を、クレデンシャルと一緒に保存することができます(タイムスタンプ = ボブがクレデンシャルを入力した時間)。例:いつ NOW - タイムスタンプ > しきい値 の場合、リクエストを拒否することがあります。
  • クロスサイトスクリプティング の保護 - 何ら変わることはないはずですよね?

これを読むのに時間を割いていただき、ありがとうございます :)

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

ああ、私はこのような質問が大好きです - セッションなしでセッションを維持すること。

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

完全なステートレス機構ではありませんが、人気のある1つの機構は、(JavaScriptを実行できると仮定して)JavaScriptにセッションクッキーを埋め込むことです。私の中のセキュリティ担当者はこれに対して悲鳴を上げていますが、実際に機能する可能性があります - すべてのリクエストに X-Authentication-Token ヘッダーのようなものを作成し、それをデータベースやメモリ上のファイルストアなどにマッピングしてユーザーを検証します。このトークンは指定した時間だけタイムアウトすることができ、タイムアウトするとユーザーは再ログインしなければなりません。データベースに格納すれば、1つのSQL文が実行され、適切なインデックスがあれば、複数のユーザーが同時にアクセスしても、実行にほとんど時間がかからないはずです。しかし、負荷テストは間違いなく役に立ちます。質問を正しく読めば、これは暗号化されたトークン機構になります。しかし、ユーザー名+パスワード+その他のものの組み合わせを使用するのではなく、たとえば32文字の暗号的にランダムなトークンを使用することを強くお勧めします。

どちらを使用するにしても、安全に送信されることを確認します。HTTPS はワイヤーを介してあなたを保護しますが、URL を介してセッション トークンを漏らすと (さらに悪いことに、URL を介して認証情報を漏らすと) あなたを保護しません。ヘッダーを使用するか、それが実行不可能な場合は、毎回 POST リクエストでトークンを送信することをお勧めします(これは、ユーザーのブラウザで隠しフォーム フィールドを意味します)。後者の POST リクエストを使用するアプローチは、念のため CSRF 防御を使用すべきですが、トークン自体を使用すると、ある種の CSRF 防御となるかもしれないと私は考えています。

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

すべての使用 (および悪用) のケースを念頭に置いていれば、おそらくこのシステムのかなり優れた実装を行うことができるはずです。