2009-06-22 2 views
38

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

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

Почему бы не использовать SessionListener и перенаправлять на сессии уничтожены? –

+4

@Mr_and_Mrs_D: потому что во время сеанса уничтожения не обязательно доступен HTTP-запрос. – BalusC

ответ

50

Вы можете использовать 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"); 
} 

Приведенный выше код не тестировался.

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

+0

как «цепочка» установлена ​​выше этого кода? – MacGyver

+0

Да, это правда. Это будет третий аргумент (значение передается) для необязательного третьего параметра (для определения метода) в методе, но doFilter - это метод объекта «цепочка» в вашем коде. Где находится «цепочка» над этой строкой кода в вашем исходном коде? – MacGyver

+0

Я не знаю, что вы имеете в виду в отношении дополнительных 3-х параметров. Переменная 'chain' передается в вашу реализацию' doFilter', контейнером. В этом ответе подразумевается, что код находится внутри 'doFilter'. –

5

Проверить для сеанса новое.

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

Ваш фрагмент восприимчив к исключениям с нулевым указателем. Передача false в 'getSession' не создаст сеанс, если он не существует и поэтому будет возвращать значение null. –

+1

'session! = Null &&! Session.isNew()' должен работать хотя;) – Yeti

+0

@Yeti, тогда зачем вообще проверять isNew(), когда мы можем сделать то же самое с одной нулевой проверкой !! :) – Jaikrat

-2

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

`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" /> 
<% { } %> 
+4

Копировальный код не сухим. Используйте фильтр. См. Также http://stackoverflow.com/questions/3177733/how-to-avoid-java-code-in-jsp-files – BalusC

+2

Совершенно отвратительное решение! – Kong

4

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

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

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

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

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

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

+0

Это может также вызвать исключение NULL-указателя при попытке прочитать атрибут, если getSession возвращает null. – Swaprks

+1

Также у вас могут быть некоторые страницы, на которых пользователь не зарегистрирован. Страницы регистрации i.e, на которых вы не получите никакой роли. –

1

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

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

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

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

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

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

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

Предполагая, что вы храните в вошедшего пользователя в сеансе в некоторых логин 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); 
     } 
    } 

} 

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

2

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