JSP与Spring MVC认证失败时如何避免页面重定向
问题分析与解决方案
核心问题
你遇到的是Spring Security认证失败时默认重定向行为导致错误提示无法在原登录页显示的问题,同时代码中存在语法错误需要修正。
步骤1:修正代码中的语法错误
你的attemptAuthentication方法里,捕获异常后抛出的语句throw new ex;是编译错误,正确写法是直接抛出捕获到的异常对象:
try{ return this.getAuthenticationManager().authenticate(authRequest); }catch(BadCredentialsException ex){ request.getSession().setAttribute("invalidCredentials", true); throw ex; // 修正此处,去掉new关键字 }
步骤2:配置Spring Security认证失败转发(而非重定向)
Spring Security默认在认证失败时会执行重定向,这会创建新的请求上下文,虽然session属性仍存在,但重定向后的GET请求会打断原请求的上下文传递。你需要配置为服务器内部转发回登录页,保留原请求的session属性。
在Spring Security配置类中,修改formLogin的配置:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") // 指定登录页的访问路径 .loginProcessingUrl("/login") // 必须与表单的action属性一致 .failureForwardUrl("/login") // 认证失败后转发回登录页 .permitAll(); } // 其他必要配置(如AuthenticationManager等) }
步骤3:确保登录页控制器支持POST请求
因为failureForwardUrl是POST请求转发,你的登录页控制器需要同时处理GET和POST请求:
@Controller public class LoginController { // 处理GET请求,显示登录页 @GetMapping("/login") public String showLoginPage() { return "login"; // 对应你的JSP视图名称 } // 处理认证失败后的POST转发请求 @PostMapping("/login") public String handleLoginFailure() { return "login"; // 返回登录页,session中的错误属性会被JSP读取 } }
原理说明
- 当认证失败抛出异常时,
failureForwardUrl会触发Spring Security将请求内部转发到登录页,而非重定向,这样session中设置的invalidCredentials、userNameRequired等属性会被保留在同一个请求上下文中,JSP的<c:if>标签能正确读取并渲染错误提示。 - 修正语法错误后,异常能被正确抛出,Spring Security才能触发预设的失败处理逻辑。
内容的提问来源于stack exchange,提问作者Shinchan
相关产品推荐
相关产品推荐

