Add secure flag to JSESSIONID cookie in spring automatically

后端 未结 5 807
广开言路
广开言路 2020-12-11 02:08

I have a tomcat application server that is behind a nginx. SSL terminates on the nginx. The Spring web-mvc application that is deployed on the tomcat should set the secure f

相关标签:
5条回答
  • 2020-12-11 02:32

    If you are using Spring Boot, there is a simple solution for it. Just set the following property in your application.properties:

    server.servlet.session.cookie.secure=true
    

    Source: Spring docs - Appendix A. Common application properties

    If you have some environment with HTTPS and some without it, you will need to set it to false in profiles without HTTPS. Otherwise the Secure cookie is ignored.

    0 讨论(0)
  • 2020-12-11 02:42

    Add another option

    You can use a ServletContextInitializer to set secure cookie and http only flag

    @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);
            }
        };
    }
    
    0 讨论(0)
  • 2020-12-11 02:45

    When you use spring-session, e.g. to persist your session in reddis, this is indeed done automatically. The cookie is than created by org.springframework.session.web.http.CookieHttpSessionStrategy which in CookieHttpSessionStrategy#createSessionCookie checks if the request comes via HTTPS and sets secure accordingly:

    sessionCookie.setSecure(request.isSecure());
    

    If you do not use spring-session, you can configure secure cookies using a ServletContextInitializer. Use a application property, to set it to true/false depending on a profile.

    @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 (used in dev when profile 'prod' is not active):

    secure.cookie=false
    

    application-prod.properties (only used when profile 'prod' is active, overwrites value in application.properties):

    secure.cookie=false
    

    start your application on the prod server with :

    --spring.profiles.active=prod
    

    Sounds like some effort, if you have not worked with profiles so far, but you will most likely need a profile for prod environment anyway, so its really worth it.

    0 讨论(0)
  • 2020-12-11 02:50

    in your application.yml just add

    server:
      session:
        cookie:
          secure: true
    
    0 讨论(0)
  • 2020-12-11 02:52

    Behind nginx as ssl terminal point it is not trivial task: secured connection must be detected by nginx header (X-Forwarded-Proto: https, see Using the Forwarded header)
    But it is easy solved by nginx config:

    if ($scheme = http) {
        return 301 https://$http_host$request_uri;
    }
    proxy_cookie_path / "/; secure";
    
    0 讨论(0)
提交回复
热议问题