Отключить загрузку HttpOnly Spring

Я хотел бы отключить сеансы HttpOnly, которые, по моему мнению, по умолчанию для Spring Boot. Как отключить HttpOnly на загрузке Spring?

В настоящее время у меня есть код, например:

@RequestMapping(value = "/stuff", method = GET)
public @ResponseBody
myObject doStuff(HttpSession session)
{
        session.setAttribute("foo", "bar");
        return  new MyObject();
}

Это возвращает заголовок ответа при вызове HTTP:

Set-Cookie: JSESSIONID=D14846D9767B6404F1FB4B013AB66FB3; Path=/; HttpOnly 

Обратите внимание на флаг HttpOnly. Я хотел бы отключить это. Как это сделать?

Боковое примечание: Да, я знаю, что httpOnly - это функция безопасности, и, отключив его, javascript может получить доступ к моему файлу cookie, то есть XSS.

Кроме того, у меня нет другой конфигурации, кроме стандартной.

@ComponentScan
@EnableAutoConfiguration
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(WebApplication.class);
        app.run(args);
    }
}

Ответ 1

Tomcat имеет контекстный атрибут с именем useHttpOnly, который проверяет:

Если флаг HttpOnly установлен на файлы cookie сеанса, чтобы предотвратить стороне script от доступа к идентификатору сеанса? По умолчанию используется значение true.

Поэтому вам нужно установить значение false. Связанная конфигурация применяется к не встроенным серверам Tomcat. Нам нужно найти способ сделать это со встроенным Tomcat.

Вот как вы это делаете. Вы объявляете метод @Bean для добавления EmbeddedServletContainerFactory в контекст. Вы настроите возвращаемый TomcatEmbeddedServletContainerFactory, указав TomcatContextCustomizer, который настраивает соответствующее свойство.

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
    factory.setTomcatContextCustomizers(Arrays.asList(new CustomCustomizer()));
    return factory;
}

static class CustomCustomizer implements TomcatContextCustomizer {
    @Override
    public void customize(Context context) {
        context.setUseHttpOnly(false);
    }
}

Это решение работает, потому что вы используете Tomcat. С различными контейнерами Servlet решение будет отличаться.

Ответ 2

Другая альтернатива принятому ответу, который подходит к загрузке spring, переопределяет способ настройки вашего EmbeddedServletContainerCustomizer.

Сначала реализуем интерфейс:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application implements EmbeddedServletContainerCustomizer

Затем добавьте переопределение для метода настройки:

@Override
public void customize(final ConfigurableEmbeddedServletContainer container)
{
    ((TomcatEmbeddedServletContainerFactory) container).addContextCustomizers(new TomcatContextCustomizer()
    {
        @Override
        public void customize(Context context)
        {
            context.setUseHttpOnly(false);
        }
    });
}

Кстати, я обнаружил, что httpOnly не был настроен вообще для меня.. поэтому мне пришлось использовать этот метод, чтобы включить httpOnly (очевидно, что мой параметр выше "true" ).

Вы также можете использовать этот метод для настройки других вещей в tomcat, таких как включение gzip для json и расширение максимального HTTP-заголовка (в случае аутентификации Kerberos мне нужно было это сделать):

((TomcatEmbeddedServletContainerFactory) container).addConnectorCustomizers(new TomcatConnectorCustomizer()
{
    @Override
    public void customize(final Connector connector)
    {
        AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
        httpProtocol.setMaxHttpHeaderSize(65536);
        httpProtocol.setCompression("on");
        httpProtocol.setCompressionMinSize(256);
        String mimeTypes = httpProtocol.getCompressableMimeTypes();
        String mimeTypesWithJson = mimeTypes + "," + MediaType.APPLICATION_JSON_VALUE;
        httpProtocol.setCompressableMimeTypes(mimeTypesWithJson);
    }
});

Ответ 3

По крайней мере, на Spring Boot >= 1.4, это еще проще, просто используйте следующее свойство:

server.session.cookie.http-only= # "HttpOnly" flag for the session cookie. configuration property.

как описано в официальной документации .