Вопрос по cookies, jboss, tomcat, jsf, jsessionid – Как избежать; jsessionid = XXX при первом обращении к странице? это работает, если первая страница JSP

15

У меня есть приложение, которое использует страницу приветствия index.jsp с<iframe></iframe> содержимое iframe является страницей jsf. Если я получаю доступ к index.jsp, я вижу cookie уже при первом попадании в firebug:

Set-Cookie  JSESSIONID=C615DA89B6EF73F801973EA3DCD3B226; Path=/

Страница из<iframe> наследует этот jsessionid. НО: когда я получаю прямой доступ к странице<iframe/> Я получаю jsessionId, переписанный на все URL без cookie - по первому запросу. После этого используется cookie. Это все хорошо - если: Система безопасности позволила бы мне переписывать URL.

Я запускаю jboss 4.2.2

Я хочу добиться того же поведения, что и с index.jsp - например, всегда используйте куки и всегда избегайте перезаписи http.

[РЕДАКТИРОВАТЬ] thanks to balusc's answer I wrote this:

public class JsessionIdAvoiderFilter implements Filter {

            public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
                    ServletException {
                boolean allowFilterChain = redirectToAvoidJsessionId((HttpServletRequest) req, (HttpServletResponse)res);

                         //I'm doing this because if I execute the request completely, it will perform a pretty heavy lookup operation. No need to do it twice.
                if(allowFilterChain)
                    chain.doFilter(req, res);
            }


            public static boolean redirectToAvoidJsessionId(HttpServletRequest req, HttpServletResponse res) {
                HttpSession s = req.getSession();
                if(s.isNew()) {

 //after the redirect we don't want to redirect again.
if(!(req.isRequestedSessionIdFromCookie()&&req.isRequestedSessionIdFromURL()))
                    {
                                //yeah we have request parameters actually on that request.         
                        String qs = req.getQueryString();

                        String requestURI = req.getRequestURI();
                        try {
                            res.sendRedirect(requestURI+"?"+qs);
                            return false;
                        } catch (IOException e) {
                            logger.error("Error sending redirect. " + e.getMessage());
                        }
                    }
                }
                return true;
            }
}

Не забудьте добавить его в свойweb.xml

    <filter> 
    <display-name>JsessionId Filter</display-name> 
    <filter-name>jsessionIdAvoiderFilter</filter-name> 
    <filter-class>my.namespace.JsessionIdAvoiderFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>jsessionIdAvoiderFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter> 

Ваш Ответ

3   ответа
13

<tracking-mode>COOKIE</tracking-mode> за это. Но, поскольку JBoss 4.2.2 не является сервлетом, совместимым с Servlet 3.0, это не вариант.

Проще всего было бы создать фильтр сервлета, который отправит перенаправление наHttpServletRequest#getRequestURI() когдаHttpSession#isNew() возвращаетсяtrue, Не забудьте проверитьHttpServletRequest#isRequestedSessionIdFromCookie() предотвращать бесконечный цикл перенаправления, когда клиент вообще не поддерживает файлы cookie.

Добро пожаловать. В правой колонке моего сайта / блога вы можете найти кнопку пожертвования PayPal. Пока это единственный путь.
Похоже, я не могу отправить вам личное сообщение. Вы должны выяснить, как заставить PayPal быть английским. Этот голландец немного сбивает с толку :-) & quot; Snel doneren & quot; :-D Toskan
О, это просто на английском для меня? Я посмотрю.
Было бы проще написать фильтр, который переопределяетHttpServletRequest.encodeURL а такжеHttpServletRequest.encodeRedirectURL просто вернутьString переданный ему аргумент: перенаправление не требуется, и в итоге вы отключаете использование идентификаторов сеансов в кодировке URL (и требующих куки).
Благодарю. Есть ли «пожертвование для доброты счастливой свиньи»? на вашем сайте где-то? Могу ли я заказать вам пиццу? Toskan
3

я попробовал это, и это работает.

    package com.rama.test.jsessionfilter

    public class JsessionIdAvoiderFilter implements Filter {

        protected static final Logger LOGGER = LogManager.getLogger(JsessionIdAvoiderFilter.class);

        public void doFilter(ServletRequest req, ServletResponse res,
                FilterChain chain) throws IOException, ServletException {

            if (!(req instanceof HttpServletRequest)) {
                chain.doFilter(req, res);
                return;
            }

            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;

        // Redirect requests with JSESSIONID in URL to clean old links
        /* If you really want clean up some old links which have Jsession id bookmarked clean it. If its new app 
            this  below check is not required. */
            if (request.isRequestedSessionIdFromURL()) {
                String url = request.getRequestURL().append(request.getQueryString() != null ? "?"
                                + request.getQueryString() : "").toString();
                response.setHeader("Location", url);
                response.sendError(HttpServletResponse.SC_MOVED_PERMANENTLY);
                LOGGER.info(" Found url with jsession id in it:"+ request.getRequestURL() +": url="+url);
                return;
            }

            // Prevent rendering of JSESSIONID in URLs for all outgoing links
            HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(
                    response) {
                @Override
                public String encodeRedirectUrl(String url) {
                    return url;
                }

                @Override
                public String encodeRedirectURL(String url) {
                    return url;
                }

                @Override
                public String encodeUrl(String url) {
                    return url;
                }

                @Override
                public String encodeURL(String url) {
                    return url;
                }
            };
            chain.doFilter(req, wrappedResponse);

        }

        public void destroy() {
        }

        public void init(FilterConfig arg0) throws ServletException {
        }
    }

и следующая запись в web.xml

<filter> 
        <display-name>JsessionId Filter</display-name> 
        <filter-name>jsessionIdAvoiderFilter</filter-name> 
        <filter-class>com.rama.test.jsessionfilter.JsessionIdAvoiderFilter</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>jsessionIdAvoiderFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

Работает отлично !!!.

Если куки отключены, вам лучше проверить свой код и дать предупреждение. Предполагается, что cookie включен на стороне клиента.
2

Это можно сделать с помощью простого фильтра, который упаковывает запрос с помощью HttpServletRequest, который переопределяет HttpServletRequest.encodeURL и HttpServletRequest.encodeRedirectURL. Просто верните переданный ему аргумент String, и вы отключите перезапись URL. Обратите внимание, что это будет работать только для одного веб-приложения, если вы не хотите настроить его вconf/web.xml (не рекомендуется) или настройте его во всех ваших отдельных веб-приложениях.

Этот метод превосходит тот, который был опубликован позже в вашем вопросе, потому что он не требует перенаправления, которое может замедлить ваши запросы. IMO, это также чище.

я посмотрим на это как можно скорее. Что вы имеете в виду под "одиночным"? WebApp? Я не совсем уверен, что вы имеете в виду Toskan
Фильтры настроены вWEB-INF/web.xml который будет защищать только одно веб-приложение, как описано.
причина, по которой я принимаю балюсный ответ, заключается в том, что это то, что я реализовал, и это хорошо подходит для описанной проблемы - у меня нет времени, чтобы опробовать ваше решение, но это звучит хорошо Toskan

Похожие вопросы