web-dev-qa-db-ja.com

ステートレスWebアプリアーキテクチャのすべてのリクエストでDBにアクセスしてユーザーを認証することを避けますか?

概要

ユーザーがWebサイトにログインし、ユーザー名/パスワードの資格情報が検証されてアクティブなセッションが確立されたら、そのユーザーからのすべてのリクエストに対してDBにアクセスすることを回避できますか?セッションの存続期間中、後続のリクエストを安全に認証し、DBクエリやその他の内部ネットワークトラフィックを最小限に抑えるための推奨される方法は何ですか?

背景

ステートレスWebアプリサーバーアーキテクチャでは、各リクエストがユーザーからの以前のアクティビティをまったく認識していないため、そのユーザーからのすべてのリクエストについてDBにクエリを実行する必要があります(通常、Cookieに保存されているセッションIDをクエリして、リクエストヘッダーで転送されます)。しかし、基本的な情報が暗号化されて、セッションCookieに保存され、機密性が低く、編集不可能なリクエストに対してユーザーを検証するのに十分な情報がある場合はどうでしょうか。このようなリクエストの場合、例として、ユーザーIDと彼のマシンを可能な限り一意に識別するもの(ユーザーエージェント+ IPアドレス)を暗号化してセッションデータに格納できます。データの暗号化に使用されるキーは毎日変更される可能性があり、ハッカーが別のマシンにセッションデータのクローンを作成することが困難になります。セッションの有効期限が切れたら、ユーザーの資格情報を完全に検証する必要があります。実際、ユーザーのセッションをハッキングする最大の脅威は、ユーザーのコンピューターを使用している人が、その人が立ち去ったことです。これについて心配する必要はありません。WebアプリケーションサーバーとDB間のある程度のキャッシングで認証プロセスを効率化できますか?不必要な最適化のように思えるかもしれませんが、すべてのリクエストでこのプロセスが必要になるため、効率の改善の準備が整っているようです。提案をありがとう!

38
onlinespending

はい可能であり、この手法は広く使用されています。

ステートフルセッションと比較して、いくつかのマイナーな欠点があります。

  1. 強力なログアウトはサポートしていません。ユーザーがログアウトをクリックすると、Cookieはブラウザーから消去されます。ただし、攻撃者がCookieを取得した場合、Cookieの有効期限が切れるまでそれを使用し続けることができます。
  2. サーバー側のシークレットを使用してトークンを作成すると、単一障害点が作成されます。シークレットがキャプチャされた場合、攻撃者は任意のユーザーになりすますことができます。

ステートレスセッションとステートフルセッションのどちらを使用するかは、パフォーマンスとセキュリティの要件によって異なります。オンラインバンキングではステートフルセッションを使用する傾向があり、忙しいブログではステートレスセッションを使用する傾向があります。

提案されたスキームにはいくつかの調整が必要です。

  1. トークンを暗号化しても、改ざんからトークンを保護することはできません。改ざんを防止するメッセージ認証コード(MAC)を使用したい。さらに暗号化を使用することもできますが、それはそれほど重要ではありません。
  2. トークンにタイムスタンプを含め、有効期限を設定する必要があります。どこか約15分が賢明です。通常、タイムアウトの直前に自動的に再発行され、通常、再発行によってデータベースヒットが発生します(ただし、それを回避することもできます)。
  3. トークンにユーザーのIPアドレスを含めないでください。モデムのリセット、WiFiホットスポットの変更、プロキシの負荷分散などにより、約3%のユーザーがWebセッション中に合法的にIPアドレスを変更します。トークンにユーザーエージェントを含めることはできますが、これは通常のことではありません。自分が何をしているのかが確実にわかっている場合は、高度なテクニックと考えてください。
  4. 攻撃者がセッションCookieをキャプチャすると、そのユーザーになりすますことができます。あなたが本当にできることは何もありません。代わりに、攻撃者が最初にCookieをキャプチャするのを防ぐために、あらゆる努力を払ってください。 SSLを使用し、「安全な」Cookieフラグを使用し、すべてのクロスサイトスクリプティングの欠陥を修正します。また、コンピューターが無人のときに画面をロックするようユーザーにアドバイスします。

これがお役に立てば幸いです。不明な点がある場合、またはさらに情報が必要な場合は、コメントを残してください。さらにお手伝いできるかどうかを確認します。

42
paj28

一般的に、認証データなどの機密情報でさえ、クライアントに状態情報を「保存」することが可能です。このようなストレージは、サーバー上のリソースを節約するために使用されます。データベースの負荷を最小限に抑えるため。これらの以前の質問を参照してください:

簡単に言えば、サーバーに情報sを保存し、同じクライアントが戻ってきたときに検索する場合は、代わりにCookieとしてクライアントに送信できます。 。 encryptionが必要な場合があります。これは、その情報が「プライベート」である可能性があるためです。 integrityは、クライアントが同意なしにデータを変更できないようにするためにおそらく必要です。したがって、暗号化と [〜#〜] mac [〜#〜] の両方、または両方を適切に実行するこれらの気の利いた暗号化モード( [〜#〜 ] gcm [〜#〜] は、そのためによく引用される標準です)。

一般的に、クライアントとクライアントに状態情報を保存すると、その情報のライフサイクルを制御できなくなります。クライアントは、Cookieを送り返さないように選択することができます。つまり、新しい新鮮なクライアントをシミュレートします。また、クライアントは古いcookie値を返す場合があります。これが問題であるかどうかは、正確な状況によって異なります。 Cookieデータにタイムスタンプを含めて、本当に古すぎるCookie値を認識できるようにすることをお勧めします。

16
Thomas Pornin

この問題を解決する方法はいくつかあります(REST APIs)でこの方法が使用されているのを見てきました)。

  1. HTTPsを使用して認証し、ステートレスAPIを使用します。
  2. 基本的なHTTP認証方法を使用し、各リクエストで期限切れのtokenIDを使用します。

いずれにしても、認証とステートレスが必要な場合は、アプリセッションで認証を管理する必要があります。資格情報を確認した後、信頼できるユーザーなどを介して再度作成しなくても、実際にデータベースクエリを実行できます。

資格情報の確認後に、許可したユーザー以外のユーザーからデータベースへの直接接続を許可しないようにしてください。

1
kiBytes

以前の認証に基づく認証を省略すると、Webアプリケーションがセッションアプリケーションになることを理解していると思います。認証されたセッション状態ではありませんか?あなたがセッションを持つためにスタッドしていることを知っています。セッションリースの申請が必要な理由を自問することもできます。通常、人々は2つの主な理由でセッションリーアプリケーションを必要とします。クライアントとサーバーファームのメンバーとの依存関係を気にすることなく、要求を異なるサーバーに配信できます。多数のユーザーが同時にアクセスしている場合のメモリリンケージ。セッションアプリケーションでも、認証時にサーバーに暗号化された署名済みトークンを発行させ、Webファームの他のメンバーがそのトークンを確認してユーザーが正当である可能性があることを認識できるようにすることで、これらの要件を満たすことができます。次のリクエストには同じトークンが必要なため、なりすましは引き続き可能です。リクエストのhttpヘッダーとIPからのトークンデータにその使用を制限するために含めることができますが、ミドルプロキシはNATを実行し、クライアントヘッダーをコピーすることでトークンを使用できます。中間者攻撃は、httpsによって認証要求を保護し、クライアントに資格情報とともにランダムに生成されたキーを送信させ、これを使用して要求の署名を復号化します。各要求のクライアントは、要求の一部のデータを暗号化します署名として。暗号化されたデータは、セッションIDと、事前に確立されたシーケンサージェネレーターからのシーケンス要素にすることができます。予測可能な動作のため、1ずつインクリメントしたものを使用しないでください。各リクエストと同様に、この署名は以前の署名とは異なり、クライアントが認証されていることを確認できます。シーケンサージェネレーターが常にインクリメントしている場合は、フルチェックの前に単純なチェックを行うために使用された最後の要素をキャッシュできます。ファームの他のメンバーに要素をブロードキャストしますセッションID内で使用されるシーケンスのt。要素が無効な場合にのみ応答します。要素シーケンスは、応答サーバーの以前の要求で使用されている場合、またはシーケンスの次の要素がキャッシュでタイムアウトした場合は無効です。メモリリネージの防止は、この情報を永続化し、最も頻繁に使用される情報のみをメモリに保持するために、各メンバーファームにSQLサーバーを実装することです。ファームメンバー間の通信に使用されるネットワークのデバイスは、通信が安全でないため、すべてアプリケーションの所有者が管理する必要があります。この構造により、スケーラビリティが保証されます。

0
Oscar Gras