如何配置Spring Boot Security将JSESSIONID从Cookie改为Header传输?
配置Spring Boot Security自定义JSESSIONID的传递方式
要实现不在Cookie中返回JSESSIONID,而是通过响应Header传递,同时让Security识别请求Header中的JSESSIONID,可以通过自定义Session ID解析器并修改Security配置来完成,具体步骤如下:
1. 自定义Session ID解析器
创建一个继承AbstractHttpSessionIdResolver的自定义解析器,实现从请求Header读取JSESSIONID,并将会话ID写入响应Header(同时清除默认的Cookie设置):
import org.springframework.session.web.http.AbstractHttpSessionIdResolver; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Collections; import java.util.List; public class HeaderSessionIdResolver extends AbstractHttpSessionIdResolver { private static final String JSESSIONID_HEADER = "JSESSIONID"; // 从请求Header中读取JSESSIONID @Override public List<String> resolveSessionIds(HttpServletRequest request) { String sessionId = request.getHeader(JSESSIONID_HEADER); return sessionId != null ? Collections.singletonList(sessionId) : Collections.emptyList(); } // 将JSESSIONID写入响应Header,并清除默认的Set-Cookie头 @Override public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) { response.setHeader(JSESSIONID_HEADER, sessionId); // 禁用默认的Cookie会话ID设置 response.setHeader("Set-Cookie", "JSESSIONID=; Max-Age=0; Path=/; HttpOnly"); } // 会话过期时清理Header @Override public void expireSession(HttpServletRequest request, HttpServletResponse response) { response.setHeader(JSESSIONID_HEADER, ""); response.setHeader("Set-Cookie", "JSESSIONID=; Max-Age=0; Path=/; HttpOnly"); } }
2. 配置Spring Security使用自定义解析器
根据你的Spring Boot/Spring Security版本,选择对应的配置方式:
方式一:适用于Spring Security 5.7+(推荐,弃用WebSecurityConfigurerAdapter)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.session.web.http.SessionIdResolver; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .sessionManagement(sessionConfig -> sessionConfig .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) .sessionIdResolver(headerSessionIdResolver()) // 指定自定义解析器 ); // 可添加其他认证/授权规则,例如: // .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) // .formLogin() 等 return http.build(); } @Bean public SessionIdResolver headerSessionIdResolver() { return new HeaderSessionIdResolver(); } }
方式二:适用于旧版本(使用WebSecurityConfigurerAdapter)
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.session.web.http.SessionIdResolver; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) .sessionIdResolver(headerSessionIdResolver()); // 指定自定义解析器 // 添加其他认证/授权配置 } private SessionIdResolver headerSessionIdResolver() { return new HeaderSessionIdResolver(); } }
效果验证
- 客户端认证成功后,响应Header中会包含
JSESSIONID: <会话ID>,且不会返回Set-Cookie头。 - 后续请求只要在请求Header中携带
JSESSIONID: <会话ID>,Spring Boot Security就能识别已认证的会话。
内容的提问来源于stack exchange,提问作者Maverick
相关产品推荐
相关产品推荐

