認証を必要とするRESTサービスを実装しています。このサービスはデータベースに直接アクセスできないため、ランダムに生成されたトークンなどのユーザーごとの状態を保存できません。別のバックエンドサービスへ。
私が思いついた解決策は、ユーザーが認証するときにJSON Webトークン( [〜#〜] jwt [〜#〜] )を作成することです。 JWTクレームセットには、Subject( "sub")フィールドにユーザーIDが含まれています。次に、サーバーは、256ビットキーのAES GCM( "enc": "A256GCM")を使用してクレームセット( "alg": "dir")を直接暗号化し、 [〜#〜] jwe [〜#〜]を作成します。 。キーは、サービスの開始時に一度生成され、メモリに保存されます。
認証するために、クライアントはユーザー名/パスワードを送信し、サーバーは上記のトークンで応答します。次に、クライアントは後続の各要求でそのトークンを送信します。
クライアントが後続のリクエストでトークンを送信すると、サーバーはキーを使用してトークンを復号化し、「sub」フィールドのユーザーIDを現在のユーザーのIDであると想定します。認証チェック。トークンの有効期限は、JWTクレームセットの「exp」フィールドによって処理されます。
クライアントとサーバー間の接続はSSL/TLSを使用するため、トークンは漏洩しません。
私は this library を使用してJWTの作成と読み取りを行っています。自分が正しい暗号化コードを書くことを信頼していないからです。
私の質問:
基本的なアプローチは有効です。ユーザーがログインしたときにJWTを生成し、後続のメッセージにJWTが含まれることを期待し、JWTが有効であれば、後続のメッセージでJWTの件名フィールドを信頼します。ただし、注意すべき点がいくつかあります。
サーバーからデータベースにアクセスできないとのことですが、実際のログインは別の場所で処理されていると思います。ユーザーがログインしたことをサーバーがどのように認識しているかは言いませんでした。サービスとユーザーがログインしたことを知っていることとの関係に対するユーザーの認識によっては、上記の最後の2つのポイントは意味がないかもしれません。
重要なデータがない場合は、データの整合性を維持するだけで済みます。署名(JWS)トークンで十分です。
署名を行うだけの場合は、HMAC SHA-256で問題ありません。トークンの有効期限を設定し、ユーザーが手動でログアウトしたかどうかを確認することを忘れないでください(その場合、トークンを無効にします)。有効期限とログアウトを考慮に入れると、それほど心配する必要はありません(アルゴリズム的には)。単一のセッションの間に誰かがSHA-256をクラックする可能性は比較的低い(すべきです)(妥当な間隔で再認証が必要であると想定します)。
いつものように、署名するコンテンツ(ユーザー名、アカウントタイプなど)を提供することを確認してください。ユーザー定義データの署名を許可しないでください。そうしないと、危険な状況になる可能性があります。
免責事項:この投稿は厳密に私の意見です。私は自分の回答の信頼性や適合性について何も主張していません。常にセキュリティの専門家に相談して、特定のセキュリティ実装の問題について話し合う必要があります。これは純粋に教育的なものです。