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

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

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

9 ответов

Решение

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

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");
}

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

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

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

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

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

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

@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);
        }
    }

}

Затем вы можете проверить это в фильтре входа в систему, как показано ниже:

@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() чеки.

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

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);
    }
}
}

вы можете увидеть остальное в этом уроке

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

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

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

Проверка на сессию новая.

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

Вам необходимо реализовать 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/

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

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

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

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());
    }
}

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

`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" />
<% { } %>
Другие вопросы по тегам