Как отключить флаг HttpOnly в заголовке Set-Cookie при входе в Spring Boot 2.1.0 - PullRequest
0 голосов
/ 16 марта 2019

У меня проблемы с отключением флага httpOnly в заголовке set-cookie.Это в основном проблема при входе в систему, когда JSESSIONID отправляется обратно в ответ.Обратите внимание, что это на сервере Tomcat, развернутом на AWS EBS.

Любые из приведенных ниже конфигураций работают нормально, но не при развертывании.

Я пробовал следующие решения, но ни одно из них не работает

application.yml config

server:  
  servlet:
    session:
      cookie:
        http-only: false

Инициализатор контекста сервлета

@Bean
open fun servletContextInitializer(): ServletContextInitializer {
    return ServletContextInitializer { servletContext ->
        servletContext.setSessionTrackingModes(setOf(SessionTrackingMode.COOKIE))
        val sessionCookieConfig = servletContext.sessionCookieConfig
        sessionCookieConfig.isHttpOnly = false
    }

WebServerFactoryCustomizer

@Bean
open fun tomcatCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
    return WebServerFactoryCustomizer { tomcat ->
        tomcat
            .addContextCustomizers(TomcatContextCustomizer { context -> context.useHttpOnly = false })
    }

web.xml

    <session-config>
      <cookie-config>
        <http-only>false</http-only>
      </cookie-config>
    </session-config>

Пример заголовка запроса

Host: 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: 
Authorization: Bearer null
Content-Type: application/json
Content-Length: 58
Origin: 
Connection: keep-alive
TE: Trailers

Пример заголовка ответа

HTTP/2.0 200 OK
date: Sat, 16 Mar 2019 14:11:58 GMT
set-cookie: AWSALB=qBpX9uFjtkP4H7gyJ3EXL8na0a7aARiEN/twi0cc2sPywvbysKXXaNfQbe8HaS5hcC6VRnkp09VYj0pGcXiHbWRod9OithDlQ0ZIvHSbY7B5xiJT1r8N+lcRdCcp; Expires=Sat, 23 Mar 2019 14:11:57 GMT; Path=/
server: Apache/2.4.37 (Amazon) OpenSSL/1.0.2k-fips
vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers
access-control-allow-origin: 
access-control-allow-credentials: true
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
strict-transport-security: max-age=31536000 ; includeSubDomains
x-frame-options: DENY
set-cookie: JSESSIONID=70F12355ABFDD0F42292D9F6CEAA22BF; Path=/; Secure; HttpOnly
X-Firefox-Spdy: h2

1 Ответ

1 голос
/ 18 марта 2019

Я наконец смог решить эту проблему, создав Фильтр, который работает как часть Spring Security.Фильтр выполняется до SecurityContextPersistenceFilter, таким образом, ожидая, пока заголовок set-cookie добавляется, затем обновляет заголовки (перед цепочкой, получает последний вызов после выполнения doFilter ()).

Реализация фильтра

package com.zambezii.app.security.filter

import org.springframework.web.filter.GenericFilterBean
import java.io.IOException
import javax.servlet.FilterChain
import javax.servlet.ServletException
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class SessionFilter : GenericFilterBean() {

    @Throws(IOException::class, ServletException::class)
    override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
        val req = request as HttpServletRequest
        val res = response as HttpServletResponse
        chain.doFilter(req, res)

        removeHttpOnlyFlag(res)
    }

    private fun removeHttpOnlyFlag(res: HttpServletResponse) {
        val setCookieHeaderName = "set-cookie"
        var setCookieHeader = res.getHeader(setCookieHeaderName)

        if (setCookieHeader != null) {
            setCookieHeader = setCookieHeader.replace("; HttpOnly", "")
            res.setHeader(setCookieHeaderName, setCookieHeader)
        }
    }
}

Security Config

open class WebSecurityConfig() : WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
            ...
            .authenticated()
            .and()
            .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter::class.java)
            .addFilterBefore(SessionFilter(), SecurityContextPersistenceFilter::class.java)
...