Как перенаправить на страницу входа, когда сеанс истек в веб-приложении 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");
}
}
Проверьте этот пример для лучшего понимания
До времени ожидания сеанса мы получаем обычный запрос, после чего получаем запрос 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" />
<% { } %>