Spring Boot 3.3.2自定义认证过滤器认证后重定向至'/'且会话失效
问题解决思路
一、重定向后认证失败的问题解决
你的自定义认证过滤器逻辑存在漏洞——每次请求都只校验GET请求的name参数,但认证成功后,后续请求应该通过会话中存储的认证信息判断登录状态,而非重复校验name参数。
修改自定义过滤器的核心逻辑:
- 先从
SecurityContextHolder获取当前已有的Authentication对象 - 如果对象存在且已完成认证(排除匿名令牌),直接放行请求
- 仅当没有有效认证信息时,才去校验
name参数并执行认证流程
关键代码调整示例:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // 优先检查已有认证状态 Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication(); if (existingAuth != null && existingAuth.isAuthenticated() && !(existingAuth instanceof AnonymousAuthenticationToken)) { chain.doFilter(request, response); return; } // 原有校验name参数的认证逻辑 String name = httpRequest.getParameter("name"); if (name != null && !name.isEmpty()) { // 执行认证、将Authentication存入SecurityContext等逻辑 // ... } else { // 无有效认证信息,按失败处理 // ... } }
另外需确认:认证成功后SecurityContext已正确存入会话。Spring Security默认会在认证成功后将SecurityContext绑定到当前会话,后续请求会自动从会话加载SecurityContext,只要过滤器优先检查SecurityContext,就能识别已登录状态。
二、SavedRequestAwareAuthenticationSuccessHandler 保存机制详解
这个处理器的核心作用是记住用户登录前试图访问的受保护页面,认证成功后自动重定向到该页面,而非固定的默认地址。
核心流程:
- 保存请求:当用户访问受保护资源(如
/page2),Spring Security拦截器会先检查登录状态。若未登录,会将当前请求的完整信息(URL、参数、请求头等)存入会话,存储键为org.springframework.security.web.savedrequest.SavedRequest。 - 认证成功后重定向:用户完成认证后,处理器会优先从会话中查找保存的请求:
- 若找到,直接重定向到该请求地址(如
/page2),同时清除会话中保存的请求记录 - 若未找到保存的请求(比如用户直接访问带
name参数的认证地址,而非因访问受保护页面被拦截),才会使用配置的defaultTargetUrl(如/)
- 若找到,直接重定向到该请求地址(如
关于requestDispatcherPath的说明
当请求通过RequestDispatcher转发(forward)过来时,requestDispatcherPath会记录原始请求路径。这种情况下,处理器依然优先使用会话中保存的原始请求地址,仅当无保存请求时,才会 fallback 到defaultTargetUrl。比如你访问/page2?name=Bob时,若/page2是受保护资源,认证成功后会重定向到/page2,而非/。
内容的提问来源于stack exchange,提问作者Steve Maring
相关产品推荐
相关产品推荐

