2012-02-24 13 views
5

Servlet 3.0のプログラムによるセキュリティに関して、セッションがタイムアウトすると、HttpServletRequest#logout()を呼び出す方法がありません。Servlet 3.0プログラムによるセキュリティを使用する場合のセッションタイムアウトの処理方法

ユーザはJAASにログインしたままですか?

もしそうなら、セッションタイムアウト後にJAASからのログアウトを処理するベストプラクティスは何ですか?

コンテナは、セッションのタイムアウト後に再度ログインして新しいセッションを作成するという、その後のユーザーの要求をどのように処理しますか?

さておき、サーブレット3.0プログラムによるセキュリティを使用したときに、セッションのタイムアウトを処理するために、以下の3つのアプローチ使用しての長所と短所どのようなものとして:

  1. HttpSessionListener#sessionDestroyed()
  2. @ManagedBean @SessionScoped LoginManagerHttpSessionBindingListenerを実装し、中に何かを作りますvalueUnbound
  3. LoginManagerの@PreDestroyメソッドに注釈を付けます。

他に提案されているアプローチやベストプラクティスのアドバイスは、必ずお読みください。

+0

「Core Java Server Faces」p。 525は、「現在、コンテナ管理のセキュリティを使用しているときにログオフまたはアイデンティティを切り替えるための仕様がない」ことを示しています。 –

+0

また、無効化されたセッションは正式なログアウトの代用としては不十分であると訴えているが、J2EEセキュリティに関するブログの噂がいくつか出てきているが、プログラム的にログアウトする方法を提供するServlet 3.0より前に書かれたブログは古い。 –

+0

CJSFのエディションは、Servlet 3.0よりも前のバージョンであることは明らかです。 – EJP

答えて

2

サーブレット仕様のどこかに、セッションの無効性がプリンシパルがない状態に正確に対応するという声明があります。これが鍵です。 logout()とtimeoutはどちらもセッションを無効にし、セッションを無効にすると、そのセッションからプリンシパルとそのすべての値バインディングが削除されます。

JAASが実際に行うすべてのことは、LoginModulesが、ユーザと彼の役割の両方について、Subjectにプリンシパルを蓄積できることです。 JAAS logout()メソッドが本当に必要とするのは、同じモジュールのlogin()、またはおそらくcommit()というメソッドで追加された主体のSubjectをクリアすることです。これは、秘密の資格情報などを追加した場合件名。 logout()はlogin()/ commit()と同じインスタンスでは実行されないため、その削除はプリンシパルの内部コレクションではなくプリンシパルクラスに基づいている必要があります。

JAAS logout()はセッションが終了すると呼び出されませんが、プリンシパルはセッションから削除されます。

その他の理由でセッションの終了をトラッキングする場合は、ユーザーBeanをセッションバインディングリスナーにし、valueUnbound()メソッドでログアウトとしてログを記録します。これは私の経験では100%信頼できます。

その他の質問に答えるために、「JAASにログインしました」というような状態はありません。JAASは、というコンテナにログイン/ログアウトサービスを提供します。新しいログインは、前のセッションが期限切れになったかどうかにかかわらず、新しいセッションに新しいログインです。

+0

+1の簡潔な(正しい)答え=)多くの攻撃的なコメントがこのポストから削除され、(削除された)回答の一部は音に矛盾していました。終わりよければ全てよし。 – earcam

+0

ありがとう@EJP。興味深いことに、request.logout()の呼び出し後にブレークポイントを設定すると、プリンシパル_がセッションから削除されたにもかかわらず、セッションが_not_無効になっていることがわかります。 JSESSIONIDのログイン時に変更されず、セッションオブジェクトはまったく同じインスタンス(たとえば@ 15961)のままですが、これは少し不安です。もちろん、request.logout()に加えて、あるいはその代わりにsession.invalidate()を使用すると、JSESSIONID&セッションオブジェクトが変更されます。これはJBoss AS7にあります。最も重要なことは、2つのメソッドのどちらが呼び出されても、プリンシパルは削除されたということです。 –

+0

@PatrickGarnerまあ、HttpServletRequest.html.logout()のドキュメンテーションにはそういうことが書かれています。 Session.invalidate()は無効化を行いますが、現在のリクエストまたはプリンシパルには影響しません。したがって、単にそれを使用すると、ユーザーがログインしているかのように表示できます。本当に奇妙なビジネス。 – EJP

2

セッション管理はJAASに直接リンクされていません。セッション管理は実際にはコンテナによって異なります。

Jetty 8では、セッション管理は(コンテキストレベルの)SessionManagerと(サーバーレベルの)SessionIdManagerによって処理されます。

ブラウザはセッションIDをサーバーに送信します。 SessionManagerを実装するクラスは、セッションIDを検証します。セッションが期限切れの場合、セッションは無効化されて削除され、セッションリスナーに通知されます。

私はなぜあなたが「ログアウト」する必要があるのか​​分かりませんが、あなたはログアウトをリスナーにフックできるはずです。

「JAASにログインしています」というメッセージは、コンテナにあまり意味がない場合があります。 Jettyにはユーザー/プリンシパル/サブジェクトのキャッシュがないため、キャッシュを自分で実装しない限り、「ログインしていない」状態にはなりません。

JAASモジュールは単に認証と認可を提供します。他には何もない。

ADD

セッションの有効期限が切れて

は、サーバーはバック302を送信して、ログインページにリダイレクトします。ページ上のフォーム送信はログインモジュール(JAASモジュールかもしれません)を呼び出し、認証に成功すると、通常はクッキー(またはURL書き換え)の手段を介してブラウザに返される新しいセッションとセッションIDを作成します。

あなたのアプリケーションがすべてのコンテキストに対して単一のコンテキストIDを処理しない限り、セッションの有効期限が切れてもプログラム型のログアウトを実行する必要はありません。別のコンテキストで有効なセッションがまだ存在するユーザを「無効にする」ことができます。

+0

私はJAASの中身が何であるか分かりません。 WebコンテナがJAASとどのようにインターフェースするか分かりません。 Subject、Principal、およびGroupsが格納されている場所で、HttpServletRequest#logout()が呼び出されたときとセッションがタイムアウトしたときに実際に何が起こるかを示します。セッションがタイムアウトすると、HttpServletRequest#logout()が呼び出されたときにハウスキーピングが実行されますか?そうでない場合、どうしてこのような状況では必要ないのですか? –

+0

Servlet 3.0仕様を読んだ後。 JAAS仕様。 JEE 6仕様です。私は上記の質問に対する答えは分かりませんし、誰かが文書やdev-listスレッド、あるいはおそらくJBoss/Tomcat/Jetty/Glassfishの設計ドキュメントやソースコードのスニペットを教えてくれることを期待しています、プリンシパル、およびグループの各インスタンスに適用されます。 HttpServletRequest#logout()が呼び出されたときに、これらのオブジェクトに何が起こるかを知ることは素晴らしいことです。 2つの状況の下でログアウトを処理する方法の違いがあれば、それは素晴らしいでしょう。 –

関連する問題