Можно ли отключить HttpSession в web.xml?

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

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

Ответ 1

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

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

Если ваша основная проблема заключается в фактическом отключении файла cookie, который использовался за кулисами HttpSession, то вы можете в Java EE 5/Servlet 2.5 сделать это только в конфигурации webapp-сервера. Например, в 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. Это плохая идея? Я предпочитаю полностью отключать вещи, пока я им не понадоблюсь.

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

Ответ 2

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

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

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

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

Ответ 3

Если вы создаете приложение с высокой нагрузкой без состояния, вы можете отключить использование файлов 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

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

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

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

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

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

Ответ 5

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

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

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

<outbound-rule encodefirst="true">
  <name>Strip URL Session ID's</name>
  <from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
  <to>$1$2$3</to>
</outbound-rule>

Ответ 6

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

Ответ 7

В 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>

Кстати, разница между NEVER и STATELESS

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

БЕЗОПАСНОСТЬ: Spring Безопасность никогда не создаст HttpSession, и она будет никогда не используйте его для получения SecurityContext

Ответ 8

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

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