You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security过滤器中后续请求的Cookie传递问题解决

跨域名重定向丢失认证Cookie导致403的解决方案

我们的应用使用两个域名:example.com(公开域名)和my.example.com(仅面向已登录用户)。当用户从example.com发起需要认证的REST请求时,会触发Spring Security过滤器重定向到my.example.com,但重定向后的请求丢失了认证Cookie,导致403错误。

问题根源

  1. Cookie Domain限制:若认证Cookie的Domain仅设置为example.com,浏览器会限制该Cookie只能在example.com域名下发送,不会携带到子域my.example.com的请求中。
  2. CORS配置冲突:当前代码同时设置Access-Control-Allow-Origin: *和Access-Control-Allow-Credentials: true,这是浏览器禁止的组合——允许携带凭证时,Origin不能用通配符*,必须指定具体域名。
  3. 重定向未主动传递Cookie:重定向响应中未将原请求的Cookie重新绑定到目标域名,导致浏览器跳转后无法获取认证凭证。

解决方案

1. 修正认证Cookie的Domain设置

在生成认证Cookie(如Spring Security的JSESSIONID或自定义认证Cookie)时,将Domain设置为.example.com,让两个域名共享该Cookie:

Cookie authCookie = new Cookie("AUTH_TOKEN", tokenValue);
authCookie.setDomain(".example.com"); // 前缀点表示覆盖主域及所有子域
authCookie.setPath("/");
authCookie.setHttpOnly(true); // 安全配置,防止XSS攻击
authCookie.setSecure(true); // 生产环境建议开启,仅通过HTTPS传输
response.addCookie(authCookie);

2. 修复CORS配置冲突

修改addCorsHeaders方法,动态获取请求Origin并指定允许的域名,同时确保允许携带凭证:

private void addCorsHeaders(HttpServletRequest request, HttpServletResponse response) {
    String origin = request.getHeader("Origin");
    // 白名单校验,仅允许指定域名
    if (origin != null && (origin.contains("example.com"))) {
        response.setHeader("Access-Control-Allow-Origin", origin);
    }
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Cookie"); // 明确允许携带Cookie头
    response.setHeader("Access-Control-Allow-Credentials", "true");
}

调用该方法时需传入HttpServletRequest以获取请求Origin。

3. 重定向时主动复制Cookie

在过滤器的重定向分支中,将原请求的Cookie重新设置到响应中,绑定到目标域名:

else {
    String redirectUrl = getUrlToRedirect(myUrl, httpServletRequest);
    // 传入request修复CORS头
    addCorsHeaders(httpServletRequest, httpServletResponse);

    // 复制原请求的Cookie到响应,设置正确Domain
    Cookie[] cookies = httpServletRequest.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            Cookie newCookie = new Cookie(cookie.getName(), cookie.getValue());
            newCookie.setDomain(".example.com"); // 或直接指定"my.example.com"
            newCookie.setPath("/");
            newCookie.setHttpOnly(cookie.isHttpOnly());
            newCookie.setSecure(cookie.isSecure());
            httpServletResponse.addCookie(newCookie);
        }
    }

    httpServletResponse.setHeader("Location", redirectUrl);
    httpServletResponse.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
}

额外注意事项

  • 检查浏览器第三方Cookie设置:部分浏览器默认阻止第三方Cookie,需提示用户将example.com和my.example.com加入例外列表。
  • 生产环境强制HTTPS:配合Cookie的Secure属性,确保Cookie仅通过安全通道传输,避免被拦截窃取。

内容的提问来源于stack exchange,提问作者Joe D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:15:26