Могу ли я отключить HttpSession в web.xml? - PullRequest
55 голосов
/ 13 февраля 2010

Я хотел бы полностью исключить HttpSession - могу ли я сделать это в web.xml? Я уверен, что существуют конкретные способы сделать это (именно это приводит к тому, что результаты поиска переполняются, когда я выполняю поиск в Google).

P.S. Это плохая идея? Я предпочитаю полностью отключать вещи, пока они мне действительно не нужны.

Ответы [ 9 ]

73 голосов
/ 13 февраля 2010

Я бы хотел полностью исключить HttpSession

Вы не можете полностью отключить его. Все, что вам нужно сделать, это просто , а не , чтобы получить хендл с помощью request.getSession() или request.getSession(true) в любом месте кода вашего веб-приложения и убедиться, что ваши JSP не делают этого неявно, установив <%@page session="false"%>.

Если ваша главная задача на самом деле - отключить cookie, который использовался за кулисами HttpSession, то в Java EE 5 / Servlet 2.5 вы можете сделать это только в конфигурации веб-приложения для конкретного сервера. Например, в Tomcat можно установить для атрибута cookies значение false в элементе <Context>.

<Context cookies="false">

См. Также Специальная документация Tomcat . Таким образом, сеанс не будет сохранен в последующих запросах, которые не перезаписываются по URL - только всякий раз, когда вы по какой-то причине извлекаете его из запроса. В конце концов, если вам это не нужно, просто не захватывайте его, тогда оно вообще не будет создано / сохранено.

Или, если вы уже используете Java EE 6 / Servlet 3.0 или новее и действительно хотите сделать это с помощью web.xml, тогда вы можете использовать новый элемент <cookie-config> в web.xml следующим образом, чтобы обнулить максимальный возраст:

<session-config>
    <session-timeout>1</session-timeout>
    <cookie-config>
        <max-age>0</max-age>
    </cookie-config>
</session-config>

Если вы хотите жестко закодировать в своем веб-приложении так, чтобы getSession() никогда не возвращал HttpSession (или "пустой" HttpSession), тогда вам нужно будет создать фильтр, прослушивающий url-pattern из /*, который заменяет HttpServletRequest реализацией HttpServletRequestWrapper, которая возвращает все getSession() методы null, или фиктивной пользовательской реализацией HttpSession, которая ничего не делает или даже выдает UnsupportedOperationException .

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
        @Override
        public HttpSession getSession() {
            return null;
        }
        @Override
        public HttpSession getSession(boolean create) {
            return null;
        }
    }, response);
}

P.S. Это плохая идея? Я предпочитаю полностью отключать вещи, пока они мне действительно не нужны.

Если они вам не нужны, просто не используйте их. Это все. Действительно:)

7 голосов
/ 28 октября 2015

Если вы создаете приложение с высокой нагрузкой без сохранения состояния, вы можете отключить использование файлов cookie для отслеживания сеанса следующим образом (не навязчиво, возможно, не зависит от контейнера):

<session-config>
    <tracking-mode>URL</tracking-mode>
</session-config>

Для реализации этого архитектурного решения напишите что-то вроде этого:

public class PreventSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
    throw new IllegalStateException("Session use is forbidden");
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
    throw new IllegalStateException("Session use is forbidden");
}
}

И добавьте его в web.xml и исправьте места, где он не работает, за исключением:

<listener>
    <listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
4 голосов
/ 30 декабря 2013

Я использую следующий метод для своего приложения RESTful, чтобы удалить все непреднамеренные сеансовые куки-файлы из созданных и используемых.

<session-config>
    <session-timeout>1</session-timeout>
    <cookie-config>
        <max-age>0</max-age>
    </cookie-config>
</session-config>

Однако это не отключает HttpSessions в целом. Приложение может по-прежнему непреднамеренно создавать сеанс, даже если он исчезает через минуту, а мошеннический клиент также может игнорировать запрос максимального возраста для файла cookie.

Преимущество этого подхода в том, что вам не нужно менять приложение, просто web.xml. Я бы порекомендовал вам создать HttpSessionListener, который будет регистрировать, когда сеанс создается или уничтожается, чтобы вы могли отслеживать, когда это происходит.

2 голосов
/ 19 июля 2018

Начиная с Servlet 3.0, вы можете сделать так, чтобы сеансы не отслеживались контейнером сервлета каким-либо образом, добавляя такой код в метод contextInitialized для ServletContextListener:

servletContext.setSessionTrackingModes(Collections.emptySet());

Javadoc.

2 голосов
/ 10 февраля 2017

В Spring Security 3 с Java Config вы можете использовать HttpSecurity.sessionManagement ():

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

Xml выглядит так;

<http create-session="stateless">
  <!-- config -->
</http>

Кстати, разница между НИКОГДАМИ и STATELESS

НИКОГДА: Spring Security никогда не создаст HttpSession, но будет использовать HttpSession, если он уже существует

STATELESS: Spring Security никогда не создаст HttpSession и будет никогда не используйте его для получения SecurityContext

2 голосов
/ 13 февраля 2010

Вместо отключения вы можете перезаписать URL с помощью фильтра перезаписи URL, например, фильтр перезаписи tuckey .Это даст Google дружественные результаты, но все же разрешит обработку сеансов на основе файлов cookie.

Однако вам, вероятно, следует отключить его для всех ответов, поскольку это хуже, чем просто недружественная поисковая система.Он предоставляет идентификатор сеанса, который можно использовать для определенных эксплойтов безопасности .

Пример конфигурации для фильтра Tuckey:

<outbound-rule encodefirst="true">
  <name>Strip URL Session ID's</name>
  <from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
  <to>$1$2$3</to>
</outbound-rule>
2 голосов
/ 13 февраля 2010

Я хотел бы полностью исключить HttpSession - могу ли я сделать это в web.xml? Я уверен, что существуют конкретные способы сделать это

Я так не думаю. Отключение HttpSession было бы нарушением спецификации сервлета, которая гласит, что HttpServletRequest#getSession должен вернуть сеанс или создать его. Поэтому я не ожидал бы, что контейнер Java EE предоставит такую ​​опцию конфигурации (которая сделает его несовместимым).

Это плохая идея? Я предпочитаю полностью отключать вещи, пока они мне действительно не понадобятся.

Ну, я не совсем понимаю, просто не вкладывайте ничего в сессию, если вы не хотите ее использовать. Теперь, если вы действительно хотите запретить использование сеанса, вы можете использовать Filter, чтобы заменить запрос реализацией HttpServletRequestWrapper, переопределяющей getSession(). Но я бы не стал тратить время на реализацию этого:)

Обновление: Мое первоначальное предложение было неоптимальным, "правильный" ( кашель ) был бы заменой запроса.

1 голос
/ 26 сентября 2012

Для приложения RESTful я просто аннулирую его каждый раз, когда заканчивается жизненный цикл запроса. Может быть какой-то веб-сервер, который всегда создает новый сеанс при доступе нового клиента, звоните ли вы request.getSession() или нет.

0 голосов
/ 18 сентября 2014

Нельзя избежать создания сеанса. Но вы можете проверить, нарушаете ли вы свои собственные требования в конце цикла запроса. Итак, создайте простой фильтр сервлета, который вы помещаете как первый, так и после chain.doFilter, генерируете исключение, если сеанс создан:

chain.doFilter(request, response);
if(request.getSession(false) != null)
    throw new RuntimeException("Somewhere request.getSession() was called");
...