session污染本质是cookie跨应用透传,需从路径、域名、名称三方面硬隔离:①用proxypassreversecookiepath和后端sessioncookiepath限定cookie作用路径;②用proxypassreversecookiedomain统一domain属性;③为各应用配置唯一session cookie名。

Apache 代理多个后端应用(如 /app1 和 /app2)时,Session 污染的本质是:浏览器把本该只属于某个应用的 Cookie(如 JSESSIONID)错误地带给了另一个应用,导致登录态错乱、会话覆盖甚至越权访问。解决关键不是让 Apache 管理 Session,而是切断 Cookie 的跨应用透传路径——从路径、域名、名称三方面做硬隔离。
隔离 Cookie 的作用路径(最有效且必须)
当两个 Java 应用都返回 Set-Cookie: JSESSIONID=abc; Path=/,浏览器访问 /app1/xxx 或 /app2/xxx 都会带上同一个 Cookie。Apache 无法自动识别路径语义,需显式重写:
- 在
app1的 location 块中加:ProxyPassReverseCookiePath / /app1/ - 在
app2的 location 块中加:ProxyPassReverseCookiePath / /app2/
这会把后端返回的Path=/改写成Path=/app1/或Path=/app2/,使浏览器仅在对应路径下发送该 Cookie。
⚠️ 同时,后端应用自身也需配合:Tomcat 设置sessionCookiePath="/app1",Spring Boot 配server.servlet.session.cookie.path=/app1。路径必须以/开头且结尾一致(如/app1/不等于/app1),否则浏览器可能不匹配。
统一并约束 Cookie 的 Domain 属性
若后端返回 Domain=192.168.1.10 或 Domain=localhost,浏览器可能在开发环境误将 Cookie 发送给其他子路径应用。用 ProxyPreserveHost Off + ProxyPassReverseCookieDomain 控制:
- 添加:
ProxyPassReverseCookieDomain 192.168.1.10 .example.com - 或更通用:
ProxyPassReverseCookieDomain localhost .example.com
带前导点的.example.com表示通配所有子域(如app1.example.com、app2.example.com),但对/app1这类路径部署仍需配合Path隔离。若各应用已部署在独立子域(app1.example.com、app2.example.com),则天然隔离,无需额外干预。
为不同应用分配唯一 Session Cookie 名称
多个 Tomcat 或 Spring Boot 应用默认都用 JSESSIONID,即使路径隔离,某些框架或中间件可能忽略路径校验,直接读取该名 Cookie。应主动差异化命名:
- Tomcat:在
context.xml中设<manager sessioncookiename="APP1_JSESSIONID"></manager> - Spring Boot:配置
server.servlet.session.cookie.name=APP1_SESSION_ID
Apache 不需要为此改配置(ProxyPassReverseCookiePath对名称无感),但需确保后端生成的 Cookie 名与路径、Domain 一同生效。名称差异能从根本上避免误读——APP1_JSESSIONID和APP2_JSESSIONID互不干扰。
不推荐的“伪解法”要避开
-
stickysession(粘性会话)只解决负载均衡下的节点漂移,不防跨应用污染; -
ip_hash或 Tomcat session 复制会让所有节点共享全部 Session,反而扩大污染面; - 依赖 Redis 共享 Session 是为集群扩展设计的,多应用共存时若未分 namespace(如 key 前缀
app1:sess:vsapp2:sess:),仍会互相覆盖。
真正干净的方案,是让每个应用的 Session Cookie 在浏览器层面就彼此“看不见”。











