Spring Boot Todo应用登录后按用户ID重定向至/todo/{id}问题求助
解决Spring Boot登录后动态重定向至带用户ID的待办页面问题
要实现登录后根据用户ID重定向到/todo/{id},不能直接通过defaultSuccessUrl配置占位符路径,因为Spring Security无法在这里动态填充用户参数。需要通过自定义登录成功处理器来实现动态重定向逻辑,步骤如下:
1. 自定义AuthenticationSuccessHandler
创建处理器类,在登录成功后获取当前用户ID并构造重定向URL:
import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collections; import org.springframework.security.core.authority.SimpleGrantedAuthority; public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { // 从认证信息中获取当前登录的User对象 User currentUser = (User) authentication.getPrincipal(); // 构造目标重定向路径 String targetUrl = "/todo/" + currentUser.getId(); // 执行重定向 response.sendRedirect(targetUrl); } }
2. 修改SecurityConfig配置
替换原有的defaultSuccessUrl,使用自定义的成功处理器:
@Configuration @EnableWebSecurity public class SecurityConfig { @Autowired private UserRepository userRepository; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.formLogin(login -> login .loginPage("/login") .loginProcessingUrl("/login") // 使用自定义登录成功处理器 .successHandler(new CustomAuthenticationSuccessHandler()) .failureUrl("/login?error") .permitAll()) .authorizeHttpRequests(authz -> authz .mvcMatchers("/css/**").permitAll() .mvcMatchers("/signup").permitAll() .anyRequest().authenticated() ) .authenticationProvider(authenticationProvider()); http.logout().permitAll(); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(customUserDetailsService()); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } @Bean public UserDetailsService customUserDetailsService() { return email -> { // 根据邮箱查询用户,替换为你的实际查询逻辑 User user = userRepository.findByEmail(email) .orElseThrow(() -> new UsernameNotFoundException("用户不存在:" + email)); return user; }; } }
3. 让User类实现UserDetails接口
Spring Security需要通过UserDetails获取用户认证信息,因此需让你的User实体实现该接口:
@Entity @Table(name = "users") public class User implements UserDetails { // 原有字段和getter/setter保持不变 // 实现UserDetails接口的方法 @Override public Collection<? extends GrantedAuthority> getAuthorities() { // 根据用户的authority字段返回权限列表 return Collections.singletonList(new SimpleGrantedAuthority(this.getAuthority())); } @Override public String getUsername() { // 使用邮箱作为登录用户名 return this.getEmail(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
关键说明
defaultSuccessUrl只能配置固定路径,无法动态注入用户ID这类运行时参数,因此必须通过自定义AuthenticationSuccessHandler实现动态重定向。- 确保
UserRepository实现了findByEmail方法,能正确从数据库查询到包含ID的User对象,这样才能在成功处理器中获取到用户ID。
内容的提问来源于stack exchange,提问作者funeral of tech
相关产品推荐
相关产品推荐

