문제

I'm trying to write a filter, which checks if user is logged in, and in case is not redirect him to login page. previously I had filter which actually did nothing -_- here it is, and with this filter everythig works ok, and session invalidates:

public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpSession session = request.getSession();
    if (session == null || session.getAttribute("UserName") == null) { 
        String command = request.getParameter("command");

        request.setAttribute("command", "login");
        // String page = ConfigurationManager.getInstance().getProperty(
        // ConfigurationManager.LOGIN_PAGE_PATH);

    } else {
        String username = (String) session.getAttribute("UserName");
        UserRole role;
        try {
            role = UserDAOImpl.getUserRole(username);
            session.setAttribute("role", role);
        } catch (DAOTechnicException e) {
            logger.error(e);
        } catch (DAOLogicException e) {
            logger.error(e);
        }
    }
    chain.doFilter(req, res); 
}

and when I invalidate session then it goes to (if session == null) block, and everything is ok.

but now I have another filter, here it is :

public class UserCheckFilter implements Filter {

    static class FilteredRequest extends HttpServletRequestWrapper {

        public FilteredRequest(ServletRequest request) {
            super((HttpServletRequest) request);
        }

        public String getParameter(String paramName) {
            String value = super.getParameter(paramName);
            if(value!=null){
                if (value.equals("login")) {
                    return value;
                }

                HttpSession session = super.getSession();
                if (session == null || session.getAttribute("UserName") == null) {
                    value = "login";
                }
            }
            return value;
        }
    }

    /**
     * Checks if user logged in and if not redirects to login page
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("UserName") == null) {
            if(request.getParameter("command")!=null){
                String command = request.getParameter("command");
                if(!command.equals("login")){
                    FilteredRequest filtrequest = new FilteredRequest(request);
                    String filteredvalue = filtrequest.getParameter("command");
                    chain.doFilter(filtrequest, res);
                }else{
                    chain.doFilter(req, res);
                }
            }else{
                chain.doFilter(req, res);
            }
        } else {
            String username = (String) session.getAttribute("UserName");
            UserRole role;
            chain.doFilter(req, res);
            try {
                role = UserDAOImpl.getUserRole(username);
                session.setAttribute("role", role);

            } catch (DAOTechnicException e) {
                logger.error(e);
            } catch (DAOLogicException e) {
                logger.error(e);
            }
        }

    }

in which I wrap getParameter method and check if not logged in user is trying to go to user or admin pages. But when I invalidate session, it does not invalidates, i.e. all parameters are staying the same, and then in the filter where it checks if session != null, it's not null, and in line session.setAttribute("role", role); I get exception "session is already invalidated"

here's the method where i invalidate session :

    if(request.getSession(false)!=null){
        request.getSession().invalidate();
    }
    String page = ConfigurationManager.getInstance().getProperty(
                ConfigurationManager.LOGIN_PAGE_PATH);
    return page;

and in servlet U use

RequestDispatcher dispatcher = getServletContext()
                .getRequestDispatcher(page);
        dispatcher.forward(request, response);

and btw such things with invalidating session occurs only with second filter

p.s. sorry for probably stupid question, but I really don't know what's wrong, so any suggestions would be appreciated.

도움이 되었습니까?

해결책

I think this is because you're always calling chain.doFilter().

Per Oracle's docs...

A typical implementation of this method would follow the following pattern:-

  1. Examine the request
  2. Optionally wrap the request object with a custom implementation to filter content or headers for input filtering
  3. Optionally wrap the response object with a custom implementation to filter content or headers for output filtering
  4. a) Either invoke the next entity in the chain using the FilterChain object (chain.doFilter()),
  5. b) or not pass on the request/response pair to the next entity in the filter chain to block the request processing
  6. Directly set headers on the response after invocation of the next entity in the filter chain.

In step 4, you probably want to do (b) - that is, instead of passing the request to the next filter in the chain, return the result to the user. I mean, it's an invalid session, so why bother trying to perform additional processing?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top