Как перенаправить на страницу входа, когда сеанс истек в веб-приложении Java? - PullRequest
45 голосов
/ 22 июня 2009

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

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

Ответы [ 9 ]

55 голосов
/ 22 июня 2009

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

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

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

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

18 голосов
/ 17 сентября 2015

Как перенаправить на страницу входа, когда сеанс истек в веб-приложении 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);
        }
    }

}

Затем вы можете проверить это в логине 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() чеками.

8 голосов
/ 25 февраля 2012

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

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);
    }
}
}
5 голосов
/ 16 февраля 2012

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

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

String scr = "<script>window.location=\""+request.getContextPath()+"/login.do\"</script>";
response.getWriter().write(scr);
5 голосов
/ 22 июня 2009

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

HttpSession session = request.getSession(false);
if (!session.isNew()) {
  // Session is valid
}
else {
  //Session has expired - redirect to login.jsp
}
4 голосов
/ 16 ноября 2015

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

2 голосов
/ 13 мая 2015

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

String ajaxRequestHeader = request.getHeader("X-Requested-With");
if ("XMLHttpRequest".equals(ajaxRequestHeader)) {
    response.sendRedirect("/login.jsp");
}
0 голосов
/ 17 сентября 2015

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

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());
    }
}
0 голосов
/ 31 декабря 2011

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

`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" />
<% { } %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...