web-dev-qa-db-fra.com

Comment rediriger vers la page de connexion lorsque la session a expiré dans Java?

J'exécute une application Web dans JBoss AS 5. J'ai également un filtre de servlet qui intercepte toutes les demandes adressées au serveur. Maintenant, je veux rediriger les utilisateurs vers la page de connexion, si la session a expiré. Je dois effectuer cette vérification "isSessionExpired ()" dans le filtre et rediriger l'utilisateur en conséquence. Comment fait-on ça? Je fixe ma limite de temps de session dans web.xml, comme ci-dessous:

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

Vous pouvez utiliser un Filtre et effectuer le test suivant:

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

Le code ci-dessus n'a pas été testé .

Ce n'est cependant pas la solution la plus complète. Vous devez également vérifier qu'un objet ou un indicateur spécifique à un domaine est disponible dans la session avant de supposer que, puisqu'une session n'est pas nouvelle, l'utilisateur doit être connecté. Soyez paranoïaque !

55
Alex

Comment rediriger vers la page de connexion lorsque la session a expiré dans Java?

C'est une mauvaise question. Vous devez différencier les cas "L'utilisateur n'est pas connecté" et "La session a expiré". Vous voulez essentiellement rediriger vers la page de connexion lorsque l'utilisateur n'est pas connecté. Pas lorsque la session a expiré. La réponse actuellement acceptée ne fait que vérifier HttpSession#isNew(). Mais cela échoue évidemment lorsque l'utilisateur a envoyé plus d'une demande dans la même session lorsque la session est créée implicitement par le JSP ou non. Par exemple. en appuyant simplement sur F5 sur la page de connexion.

Comme indiqué, vous devriez plutôt vérifier si l'utilisateur est connecté ou non. Étant donné que vous posez ce type de question alors que les frameworks d'authentification standard tels que j_security_check, Shiro, Spring Security, etc. gèrent déjà cela de manière transparente (et qu'il n'y aurait donc pas besoin de poser ce genre de question sur eux. ), cela signifie simplement que vous utilisez une approche d’authentification locale.

En supposant que vous stockiez l'utilisateur connecté dans la session dans une connexion servlet comme ci-dessous:

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

}

Ensuite, vous pouvez vérifier cela dans un login filtre comme ci-dessous:

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

    // ...
}

Pas besoin de bidouiller avec les contrôles HttpSession#isNew() fragiles.

18
BalusC

vous pouvez aussi le faire avec un filtre comme celui-ci:

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

À l'intérieur du filtre, injectez ce code JavaScript qui apportera la page de connexion comme celle-ci. Si vous ne le faites pas, alors dans votre AJAX appel), vous obtiendrez une page de connexion et le contenu de la page de connexion sera ajouté.

Dans votre filtre ou votre redirection, insérez ce script en réponse:

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

Check for session est nouveau.

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

Vous devez implémenter l'interface HttpSessionListener, le serveur notifiera les délais d'attente de session.

comme ça;

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

Consultez cet exemple pour mieux comprendre

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

4
Sunil Pidugu

Jusqu'à la fin de la session, nous recevons une requête normale, après quoi nous recevons une requête Ajax. Nous pouvons l'identifier de la manière suivante:

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

j'ai trouvé cette solution possible:

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
LoGos