在 spring 中自动将安全标志添加到 JSESSIONID cookie
Posted
技术标签:
【中文标题】在 spring 中自动将安全标志添加到 JSESSIONID cookie【英文标题】:Add secure flag to JSESSIONID cookie in spring automatically 【发布时间】:2017-01-08 05:45:20 【问题描述】:我有一个 nginx 后面的 tomcat 应用程序服务器。 SSL 在 nginx 上终止。 部署在 tomcat 上的 Spring web-mvc 应用程序应在 JSESSIONID 上设置安全标志。 如果 spring 对此有一些自动检测会很酷,这样我就不会在开发过程中受到打扰,因为我没有 SSL。
有没有办法告诉spring自动设置标志?
我使用 JavaConfig 设置应用程序并使用 Maven 创建可部署的战争文件。
我已经检查过了,但这看起来有点丑陋和静态: set 'secure' flag to JSESSION id cookie
【问题讨论】:
【参考方案1】:当您使用spring-session 时,例如在 reddis 中保持你的会话,
这确实是自动完成的。 cookie 是由 org.springframework.session.web.http.CookieHttpSessionStrategy
创建的,CookieHttpSessionStrategy#createSessionCookie
检查请求是否通过 HTTPS 发送并相应地设置安全:
sessionCookie.setSecure(request.isSecure());
如果您不使用 spring-session,则可以使用 ServletContextInitializer
配置安全 cookie。
使用application property,根据配置文件将其设置为真/假。
@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 环境的配置文件,所以它真的值得。
【讨论】:
CookieHttpSessionStrategy 提到当 HttpServletRequest#isSecure() 返回 true 时会自动添加安全标志。如果 ssl 在 nginx 而不是在 tomcat 上终止,那么该方法如何确定请求确实是通过 https 发送的?或者反过来,我如何告诉 tomcat 请求在某个时候是 ssl 加密的? 一般情况下,您会将 ssl 终结器设置为x-forwarded-proto = https
的请求标头,然后您的 Web 服务器可以使用它来将请求标记为 isSecure。
将secure.cookie 设置为true/false 似乎对我们没有任何帮助。我们在它前面使用了 nginx 和一个 aws 负载均衡器,所以我们需要以某种方式强制它是安全的。有没有办法强制开启?
通常你有自己的开发和生产属性,所以只需在application-prod.property/yaml
中设置server.servlet.session.cookie.secure=true
【参考方案2】:
如果您使用的是 Spring Boot,有一个简单的解决方案。只需在 application.properties
中设置以下属性:
server.servlet.session.cookie.secure=true
来源:Spring docs - Appendix A. Common application properties
如果您有一些使用 HTTPS 的环境而一些没有使用 HTTPS,则需要在没有 HTTPS 的配置文件中将其设置为 false。否则,安全 cookie 将被忽略。
【讨论】:
【参考方案3】:在你的 application.yml 中添加
server:
session:
cookie:
secure: true
【讨论】:
改用server: servlet: session: cookie: secure: true
。
server.session.cookie.secure=true
in application.properties 对我有用。【参考方案4】:
在 nginx 作为 ssl 终端点之后,这不是一项简单的任务:必须通过 nginx 标头检测安全连接(X-Forwarded-Proto: https
,请参阅Using the Forwarded header)
但是通过 nginx config 很容易解决:
if ($scheme = http)
return 301 https://$http_host$request_uri;
proxy_cookie_path / "/; secure";
【讨论】:
【参考方案5】:添加另一个选项
您可以使用 ServletContextInitializer 设置安全 cookie 和 http only 标志
@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);
;
【讨论】:
以上是关于在 spring 中自动将安全标志添加到 JSESSIONID cookie的主要内容,如果未能解决你的问题,请参考以下文章
如何使用命令行将“其他链接器标志”添加到 xcode 项目?
Wordpress 如何向所有 SETCOOKIE() 函数添加 httponly 和安全标志?