2

3 つの JSF 2.0 Web モジュールがあり、セッションの有効期限が切れたときにログイン ページにリダイレクトする必要があります。

HttpSessionListenerイベントメソッドを呼び出していますsessionDestroyed()が、そこでリクエストを転送/リダイレクトできません。HttpServletRequestオブジェクトがないからだと思いHttpServletResponseます。

も使用してみPhaseListenerましたが、ウェブブラウザで「リダイレクトが多すぎます」というエラーが発生します。

public class SessionListener implements PhaseListener {

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    public void beforePhase(PhaseEvent event) {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            try {
                System.out.println("Session Destroyed");
                FacesContext.getCurrentInstance().getExternalContext().redirect("login.jsf");
            }
            catch (Exception e) {
                System.out.println("error" + e);
            }
        }
    }

    public void afterPhase(PhaseEvent event)  {
        try {
            System.out.println("Session Created");
        }
        catch (Exception e) {
            System.out.println("error" + e);
        }
    }

}

それらの試みがうまくいかないのはなぜですか?

4

2 に答える 2

5

セッションの有効期限が切れた瞬間にリダイレクトを送信することはできません。つまり、クライアントはその時点でHTTPリクエストを送信しておらず、リダイレクトで応答できます。

ユーザーがログインしなくなったときにログインページにリダイレクトする既存の認証メカニズムを維持する必要があります。セッションの有効期限が切れたため、またはユーザーが以前にログインしたことがない(つまり、新しいリクエストである)ためにユーザーがログインページにリダイレクトされるかどうかのチェックを追加することで、せいぜい改善できます。

ifHttpServletRequest#getRequestedSessionId()が返されない場合null(つまり、クライアントがセッションCookieを送信したため、セッションがまだ有効であると見なす場合)、HttpServletRequest#isRequestedSessionIdValid()戻る場合false(つまり、サーバー側でセッションが期限切れになっている場合)で確認できます。ログインしたユーザーをチェックしているのとまったく同じフィルターでこれを行うことができます(既に1つ持っていますか?またはコンテナー管理認証を使用していますか?)。

User user = (User) session.getAttribute("user");

if (user == null) {
    String loginURL = request.getContextPath() + "/login.jsf";
    if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
        response.sendRedirect(loginURL + "?expired=true");
    } else {
        response.sendRedirect(loginURL);
    }
} else {
    chain.doFilter(request, response);
}

そして、login.xhtmlページでそれを確認します

<h:panelGroup rendered="#{param.expired}">
    <p>You have been redirected to the login page, because your session was expired.</p>
</h:panelGroup>

ちなみに、フェーズリスナーのアプローチは意味がありません。実際、すべてのリクエストに対してリダイレクトを送信し、無限ループで実行します。ビューの復元フェーズは、セッションの有効期限とはまったく関係ありません。

于 2012-06-08T14:25:10.560 に答える
0

使ってみて

 FacesContext.getCurrentInstance().getApplication().getNavigationHandler().
       handleNavigation(context, null, "LoginForm");

ただし、これらの目的には Servlet Filter を使用する必要があることに注意してください。実際にエラーが発生しやすいため、PhaseListener からのリダイレクトは行わない方がよいでしょう。

于 2012-06-08T05:54:47.500 に答える