状況:
- ユーザー名/パスワードに基づくユーザー認証を使用する Java EE Web アプリケーション
- パスワードの検証は、アプリケーション自体によって行われません。これはHttpServletRequest.login()を使用し、セキュリティ レルムはアプリケーション サーバーで定義されます。
- アプリケーションは承認を使用します (@RolesAllowed アノテーション)
- アプリケーションはユーザーを記憶できるので、毎回認証する必要はありません。
これは Web アプリケーションの非常に一般的な要件だと思いますが、最後の要件を達成するのはそれほど簡単ではなく、これを実装する標準的な方法を見つけていません。私は自分のアイデアを示し、それが完璧ではないと思う理由を説明するのが好きです。
1 HttpSession を開いたままにしておく
実際、これはそもそも私の好みの方法でした。HttpSessioin.setMaxInactiveInterval()を使用するとうまくいくと思いました。基本的にはそうですが、セッションが適切にクリーンアップされておらず、多くのユーザーがいる場合、これはリソースの問題になる可能性があります。ここで、HttpSession のクリーンアップは常に簡単ではないことを示すための私自身の質問です。
2 「remember me」Cookie を使用
する UUID を生成して Cookie として送信し、HttpSession が新しいときにそれをチェックしないのはなぜですか。これは、セキュリティ レルムが使用される唯一の目的がユーザー名/パスワードのチェックである場合、非常にうまく機能します。認証またはgetUserPrincipal()のような関数が使用されている場合、それは不可能です。パスワードの代わりにトークンを使用してHttpServletRequest.login()または同様の関数を使用する方法が見つかりませんでした。
3 「remember me」Cookie を使用し、独自の認証を使用する
確かに、これは可能ですが、一部の Bean またはメソッドへのアクセスを制限する簡単な方法が気に入っています。ユーザーがアクセスしてはいけないものにアクセスできるようなものを実装するのが難しくなります。
4 パスワードを含む「 remember me」Cookie を使用する 次!
5 「remember me」Cookie を使用してパスワードを保持する
アイデアは、パスワードと Cookie との関係を記憶することであり、HttpServletRequest.login() をパスワードとともに使用できます。これは、この回答で説明されている方法です: https://stackoverflow.com/a/5083809/210380
この方法には大きな問題があると思います:
暗号化されていないパスワード
を保存しないそれも好きじゃない。アプリケーションはどこでも使用できますが、誰かが一時的にサーバーにアクセスしてメモリ ダンプを作成したために会社のすべてのパスワードが漏洩した場合、私は責任を負いたくありません。
私の現在の解決策
これらの考えに基づいて、私は独自の解決策を考え出しました。私は2つのクッキーを使用しています。1 つ目は、 UUIDの String 表現を持つ「remember me」Cookieです。この UUID は、ユーザー名とともにメモリまたはデータベースにも記憶されます。2 番目の Cookie にも UUID の文字列表現が含まれており、パスワードの暗号化に使用されます。暗号化されたパスワードは、データベースまたはメモリ内の最初の Cookie の UUID と共に記憶されます。2 番目の Cookie の UUID は保持されません。データベースにもメモリにもありません。ユーザーパスワードを暗号化および復号化するには、 jasypt の StandardPBEStringEncryptor を使用しています。
ユーザーがこの Cookie で再認証しようとすると、両方を読み取り、最初の Cookie に基づいてユーザー名と暗号化されたパスワードを検索し、2 番目の Cookie でパスワードを復号化し、ユーザー名とパスワードで HttpServletRequest.login() を使用します。次に、サーバーに保存されている暗号化されたパスワードを削除し、2 つの新しい UUID を使用してプロセスを再開します。
質問
これに対する標準化されたソリューションは本当にありませんか?
私のソリューションには、表示されていないセキュリティ上の問題はありますか?
たとえば、再認証時に新しいキーでパスワードを暗号化するのは賢明ではない可能性がありますStandardPBEStringEncryptor はこのタスクに適していますか?
私のソリューションはやり過ぎで、時間を無駄にしていますか?
ありがとう