簡體   English   中英

在 spring 中自動將安全標志添加到 JSESSIONID cookie

[英]Add secure flag to JSESSIONID cookie in spring automatically

我有一個位於 nginx 后面的 tomcat 應用程序服務器。 SSL 在 nginx 上終止。 部署在 tomcat 上的 Spring web-mvc 應用程序應在 JSESSIONID 上設置安全標志。 如果spring對此有一些自動檢測會很酷,這樣我就不會在開發過程中受到打擾,因為我沒有SSL。

有沒有辦法告訴spring自動設置標志?

我使用 JavaConfig 設置應用程序並使用 Maven 創建可部署的戰爭文件。

我已經檢查過了,但這看起來有點丑陋和靜態: 將“安全”標志設置為 JSESSION id cookie

當你使用spring-session時,例如在 reddis 中持久化你的會話,這確實是自動完成的。 cookie 是由org.springframework.session.web.http.CookieHttpSessionStrategy創建的,它在CookieHttpSessionStrategy#createSessionCookie檢查請求是否來自 HTTPS 並相應地設置安全:

sessionCookie.setSecure(request.isSecure());

如果使用 spring-session,則可以使用ServletContextInitializer配置安全 cookie。 使用應用程序屬性,根據配置文件將其設置為真/假。

@Bean
public ServletContextInitializer servletContextInitializer(@Value("${secure.cookie}") boolean secure) {
    return new ServletContextInitializer() {

        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.getSessionCookieConfig().setSecure(secure);
        }
    };
}

application.properties(在配置文件“prod”未激活時用於開發):

secure.cookie=false

application-prod.properties(僅在配置文件“prod”處於活動狀態時使用,覆蓋 application.properties 中的值):

secure.cookie=false

使用以下命令在 prod 服務器上啟動您的應用程序:

--spring.profiles.active=prod

如果您到目前為止還沒有使用過配置文件,這聽起來像是一些努力,但無論如何您很可能需要一個用於 prod 環境的配置文件,所以它真的很值得。

如果您使用的是 Spring Boot,則有一個簡單的解決方案。 只需在application.properties中設置以下屬性:

server.servlet.session.cookie.secure=true

來源: Spring docs - 附錄 A. 常見應用程序屬性

如果您有一些使用 HTTPS 的環境而一些沒有使用 HTTPS,則需要在沒有 HTTPS 的配置文件中將其設置為 false。 否則,安全 cookie 將被忽略。

在您的 application.yml 中添加

server:
  session:
    cookie:
      secure: true

在 nginx 作為 ssl 終端點之后,這不是一項簡單的任務:必須通過 nginx 標頭檢測安全連接( X-Forwarded-Proto: https ,請參閱使用轉發標頭
但是通過 nginx 配置很容易解決:

if ($scheme = http) {
    return 301 https://$http_host$request_uri;
}
proxy_cookie_path / "/; secure";

添加另一個選項

您可以使用 ServletContextInitializer 設置安全 cookie 和僅 http 標志

@Bean
public ServletContextInitializer servletContextInitializer() {
    return new ServletContextInitializer() {
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE));
            SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
            sessionCookieConfig.setHttpOnly(true);
            sessionCookieConfig.setSecure(true);
        }
    };
}

它對我有用

public class WebInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    ctx.register(AppConfig.class);
    ctx.setServletContext(servletContext);
    Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
    servlet.addMapping("/");
    servlet.setLoadOnStartup(1);

    servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE));
    SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
    sessionCookieConfig.setHttpOnly(true);
    sessionCookieConfig.setSecure(true);
}
}

我們有一個 Spring Boot 2.3 應用程序,它在 NGINX 和 Tomcat 之間使用 HTTPS 到 NGINX 和 HTTP。

即使使用此 Spring 屬性設置:

server:
    servlet:
        session:
            cookie:
                secure: true

...當通過 HTTP 訪問應用程序時,在 JSESSIONID cookie 上設置Secure標志。 您可以通過在本地運行應用程序並使用 HTTP 與 HTTP 直接訪問 Tomcat 來測試這一點。

我發現將它添加到配置中會設置 HTTP 和 HTTPS 的 Secure 標志,這解決了使用 HTTP 將 NGINX 放在 Tomcat 前面時的問題:

/**
 * Fix for GCP... since we use HTTP internally in Kubernetes, Spring will not make JSESSIONID Secure, but this will.
 *
 * See https://www.javafixing.com/2021/11/fixed-add-secure-flag-to-jsessionid.html
 *
 * @return
 */
@Bean
public ServletContextInitializer servletContextInitializer() {
    return new ServletContextInitializer() {

        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.getSessionCookieConfig().setSecure(true);
        }
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM