3

将来のJSPベースのアプリケーションで再利用するために、非常に単純なログインおよびセッション構造を作成しました。こんな感じです:

web.xml(1分のタイムアウトは私の問題をテストするためのものです):

<session-config>
 <session-timeout>1</session-timeout>
</session-config>

<filter>
 <filter-name>Access</filter-name>
 <filter-class>com.app.Access</filter-class>
</filter>

<filter-mapping>
 <filter-name>Access</filter-name>
 <url-pattern>*</url-pattern>
</filter-mapping>

<servlet>
 <servlet-name>Login</servlet-name>
 <servlet-class>com.app.Login</servlet-class>
</servlet>

<servlet-mapping>
 <servlet-name>Login</servlet-name>
 <url-pattern>/login</url-pattern>
</servlet-mapping>

Access.javaフィルター:

// Check if the page's the login or if the user logged, else asks login
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    boolean logged = httpRequest.getSession(false) != null && httpRequest.getSession().getAttribute("user") != null;
    if (httpRequest.getServletPath().equals("/login") || logged)
        chain.doFilter(request, response);
    else
        ((HttpServletResponse) response).sendRedirect(httpRequest.getContextPath() + "/login");
}

Login.javaサーブレット(テストのために認証が短縮されました):

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid())
        request.setAttribute("failure", "session timeout");
    request.getSession().setAttribute("user", null);
    request.getRequestDispatcher("login.jsp").forward(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getSession().setAttribute("user", new User());
    response.sendRedirect("");
}

また、WebContentのルートにあるlogin.jsp<form action="login" method="post">ページには、認証用に適切なinnerHTMLと、セッションタイムアウトまたはログイン失敗メッセージを受信するための${failure}フィールドを含むフォームがあります。

この構造は私にとって完璧に機能します。インターセプト、ログインの要求、セッションと認証の両方のチェックなどがありますが、小さな欠陥があります。ログインページにアクセスし、タイムアウト後に更新(F5またはURLでEnterキーを押す)すると、ページは${failure}に「セッションタイムアウト」メッセージを表示します。

前のページがログインページであることを知らせるための実際の作業方法はまだ見つかりませんでした。タグライブラリを含むrequest.getHeader("Referer")、5つの異なる方法を試しましたが成功しませんでした。lastWish

4

2 に答える 2

1

1つの方法は、公的にアクセス可能なJSP(ログインページなど)にセッションをまったく作成させないようにすることです。つまり、JSPページを要求すると、デフォルトで暗黙的にセッションが作成されます。これは、JSPの先頭に次の行を追加することで実現できます。

<%@page session="false" %>

この方法request.getRequestedSessionId()が返さnullれるため、タイムアウトチェックはバイパスされます。この方法でセッションが作成されるのは、実際にユーザーにログインしたときだけです。サーブレットから次の行を削除するだけです。それは意味がなく、セッションを作成するからです。

request.getSession().setAttribute("user", null);
于 2012-07-01T01:27:26.603 に答える
0

私はちょうどこのようにします:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpReq = (HttpServletRequest)request;
    String servletPath = httpReq.getServletPath();
    HttpSession session = httpReq.getSession();
    String redirectUrl = "/login.jsp";
    if (
            (servletPath.endsWith("login.jsp")) ||
            (servletPath.endsWith("rss.html")) ||
            (servletPath.endsWith("httperror403.html")) ||
            (servletPath.endsWith("httperror500.html")) ||
            (servletPath.endsWith("imageMark.do"))||
            (servletPath.indexOf("/api.do") != -1) ||
            (servletPath.indexOf("/help/") != -1)){
        chain.doFilter(request, response);
    }  else if (session == null) {
        httpReq.getRequestDispatcher(redirectUrl).forward(request, response);
    } else {
        SystemUser user = (SystemUser)session.getAttribute("user");
        if (user == null){
            if (session != null){
                session.invalidate();
            }
            httpReq.getRequestDispatcher(redirectUrl).forward(request, response);
        } else {
            chain.doFilter(request, response);
        }
    }
}
于 2012-07-01T01:31:37.370 に答える