Как перенаправить на страницу входа, когда срок действия сеанса истек в веб-приложении Java?

Я запускаю веб-приложение в JBoss AS 5. У меня также есть сервлет-фильтр, который перехватывает все запросы на сервер. Теперь я хочу перенаправить пользователей на страницу входа в систему, если срок действия сессии истек. Мне нужно сделать это "isSessionExpired()" проверить фильтр и перенаправить пользователя соответственно. Как мне это сделать? Я устанавливаю ограничение времени сеанса в web.xml, как показано ниже:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>

Ответ 1

Вы можете использовать Filter и выполнить следующее тестирование:

HttpSession session = request.getSession(false);// don't create if it doesn't exist
if(session != null && !session.isNew()) {
    chain.doFilter(request, response);
} else {
    response.sendRedirect("/login.jsp");
}

Вышеприведенный код не проверен.

Однако это не самое широкое решение. Вы также должны проверить, что какой-либо предмет или флаг, определенный для домена, доступен в сеансе, прежде чем предположить, что, поскольку сеанс не является новым, пользователь должен войти в систему. Быть параноидальным!

Ответ 2

Как перенаправить на страницу входа, когда срок действия сеанса истек в веб-приложении Java?

Это неправильный вопрос. Вы должны различать случаи "Пользователь не вошел в систему" ​​и "Сессия истекла". В основном вы хотите перенаправить на страницу входа, когда пользователь не вошел в систему. Не когда сеанс истек. Текущий принятый ответ проверяет только HttpSession#isNew(). Но это, очевидно, не удается, когда пользователь отправил более одного запроса в тот же сеанс, когда сеанс неявно создан JSP или нет. Например. когда просто нажимаете F5 на странице входа.

Как сказано, вместо этого вы должны проверить, вошел ли пользователь в систему или нет. Учитывая тот факт, что вы задаете такой вопрос, в то время как стандартные рамки проверки подлинности, такие как j_security_check, Shiro, Spring Security и т.д., Уже прозрачно управляют этим (и, следовательно, нет необходимости задавать на них такой вопрос), это может означать только то, что вы используете подход, основанный на подлинной аутентификации.

Предполагая, что вы храните зарегистрированного пользователя в сеансе в некотором login servlet, как показано ниже:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @EJB
    private UserService userService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user);
            response.sendRedirect(request.getContextPath() + "/home");
        } else {
            request.setAttribute("error", "Unknown login, try again");
            doGet(request, response);
        }
    }

}

Затем вы можете проверить это в login filter, как показано ниже:

@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURI = request.getContextPath() + "/login";

        boolean loggedIn = session != null && session.getAttribute("user") != null;
        boolean loginRequest = request.getRequestURI().equals(loginURI);

        if (loggedIn || loginRequest) {
            chain.doFilter(request, response);
        } else {
            response.sendRedirect(loginURI);
        }
    }

    // ...
}

Не нужно возиться с хрупкими проверками HttpSession#isNew().

Ответ 3

Вы также можете сделать это с помощью фильтра:

public class RedirectFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req=(HttpServletRequest)request;

    //check if "role" attribute is null
    if(req.getSession().getAttribute("role")==null) {
        //forward request to login.jsp
        req.getRequestDispatcher("/login.jsp").forward(request, response);
    } else {
        chain.doFilter(request, response);
    }
}
}

Ответ 4

Проверить новый сеанс.

HttpSession session = request.getSession(false);
if (!session.isNew()) {
  // Session is valid
}
else {
  //Session has expired - redirect to login.jsp
}

Ответ 5

Внутри фильтра введите этот JavaScript, который приведет к этой странице входа. Если вы этого не сделаете, то в своем обращении к AJAX вы получите страницу входа в систему, и будет добавлено содержимое страницы входа.

Внутри фильтра или перенаправления вставьте этот script в ответ:

String scr = "<script>window.location=\""+request.getContextPath()+"/login.do\"</script>";
response.getWriter().write(scr);

Ответ 6

До таймаута сеанса мы получаем обычный запрос, после которого получаем запрос Ajax. Мы можем определить его следующим образом:

String ajaxRequestHeader = request.getHeader("X-Requested-With");
if ("XMLHttpRequest".equals(ajaxRequestHeader)) {
    response.sendRedirect("/login.jsp");
}

Ответ 7

Вам нужно реализовать интерфейс HttpSessionListener, сервер будет уведомлять об отключении сеанса.

вот так:

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class ApplicationSessionListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent event) {
   System.out.println("Session Created");
 }

public void sessionDestroyed(HttpSessionEvent event) {
   //write your logic
   System.out.println("Session Destroyed");
  }
 }

Проверьте этот пример для лучшего понимания

http://www.myjavarecipes.com/how-to-catch-session-timeouts/

Ответ 8

я нашел это возможное решение:

public void logout() {
    ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
    String ctxPath = ((ServletContext) ctx.getContext()).getContextPath();
    try {
        //Use the context of JSF for invalidate the session,
        //without servlet
        ((HttpSession) ctx.getSession(false)).invalidate();
        //redirect with JSF context.
        ctx.redirect(ctxPath + "absolute/path/index.jsp");
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }
}

Ответ 9

Когда используется журнал, введите его имя пользователя в сеанс:

`session.setAttribute("USER", username);`

В начале каждой страницы вы можете сделать это:

<%
String username = (String)session.getAttribute("USER");
if(username==null) 
// if session is expired, forward it to login page
%>
<jsp:forward page="Login.jsp" />
<% { } %>