Могу ли я отключить HttpSession в web.xml?

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

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

9 ответов

Решение

Я хотел бы полностью устранить HttpSession

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

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

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

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

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

В 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

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

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

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

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

Вместо того, чтобы отключить, вы можете переписать 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>

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

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

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

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

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

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

servletContext.setSessionTrackingModes(Collections.emptySet());

Javadoc.

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

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

chain.doFilter(request, response);
if(request.getSession(false) != null)
    throw new RuntimeException("Somewhere request.getSession() was called");
Другие вопросы по тегам