如何在Java Web应用程序中将会话过期时重定向到"登录"页面?

Vee*_*era 45 java servlets login servlet-filters

我正在JBoss AS 5中运行一个Web应用程序.我还有一个servlet过滤器,它拦截了对服务器的所有请求.现在,如果会话已过期,我想将用户重定向到登录页面.我需要执行此操作'isSessionExpired()'检查过滤器并需要相应地重定向用户.我该怎么做?我在web.xml中设置会话时间限制,如下所示:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 55

您可以使用过滤器并执行以下测试:

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");
}
Run Code Online (Sandbox Code Playgroud)

以上代码未经测试.

然而,这不是最广泛的解决方案.您还应该在会话中测试某个特定于域的对象或标志是否可用,然后再假设因为会话不是新用户必须已登录.请偏执!


Bal*_*usC 18

如何在Java Web应用程序中将会话过期时重定向到"登录"页面?

这是一个错误的问题.您应该区分"用户未登录"和"会话已过期"的情况.您基本上希望在用户未登录时重定向到登录页面.不在会话过期时.目前接受的答案只会检查HttpSession#isNew().但是当用户在JSP隐式创建会话时在同一会话中发送了多个请求时,这显然会失败.例如,只需在登录页面上按F5即可.

如上所述,您应该检查用户是否已登录.鉴于你在问这样的问题,而j_security_checkShiro,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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以在登录过滤器中检查,如下所示:

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

不需要用脆弱的HttpSession#isNew()检查来摆弄.


小智 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);
    }
}
}
Run Code Online (Sandbox Code Playgroud)

您可以在本教程中看到其余部分

  • 此外,您可能有一些用户未登录的页面.即您不会获得任何角色的注册页面. (2认同)

zka*_*hik 5

会话检查是新的.

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

  • 您的代码段易受空指针异常的影响.如果一个会话不存在则将false传递给`getSession`将不会创建会话,因此将返回null. (9认同)

小智 5

在过滤器内部注入这个JavaScript,这将带来这样的登录页面.如果您不这样做,那么在您的AJAX调用中,您将获得登录页面,并且将附加登录页面的内容.

在您的过滤器或重定向内插入此脚本作为响应:

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