Spring Security配置已认证用户访问登录页自动跳转首页
实现方案
1. 已认证用户访问登录页自动跳转首页
修改LoginController中的/login接口逻辑,在返回登录页视图前先判断当前用户认证状态,已登录用户直接重定向到首页:
@Slf4j @Controller @RequiredArgsConstructor public class LoginController { @GetMapping("/login") public String loginForm(@ModelAttribute LoginForm loginForm) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // 校验当前是否为已登录的非匿名用户 if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)) { return "redirect:/"; } return "login/loginForm"; } }
需要在类顶部引入对应依赖:
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AnonymousAuthenticationToken;
2. 注册完成后携带认证状态跳转首页
如果需要用户注册完成后无需二次登录直接跳转首页,可以在注册逻辑中手动完成认证操作,将认证信息写入安全上下文和会话,示例代码如下:
@PostMapping("/join") public String register(@Valid @ModelAttribute JoinForm joinForm, BindingResult bindingResult, HttpServletRequest request) { // 原有注册参数校验、用户信息存储逻辑保持不变 if (bindingResult.hasErrors()) { return "login/joinForm"; } // 以下代码在用户信息成功存入数据库后执行 // 1. 加载刚注册用户的权限信息 UserDetails userDetails = userSecurityService.loadUserByUsername(joinForm.getEmail()); // 2. 构造已认证的认证令牌 UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities() ); // 3. 将认证信息写入安全上下文 SecurityContextHolder.getContext().setAuthentication(authToken); // 4. 持久化认证信息到会话,避免刷新后登录状态丢失 HttpSession session = request.getSession(true); session.setAttribute( HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext() ); // 直接重定向到首页,无需跳转登录页 return "redirect:/"; }
需要引入的对应依赖:
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;
3. 优化:避免未认证用户访问登录页自动创建无效会话
如果需要解决匿名用户访问登录页时Spring Security自动创建空会话的问题,可以在WebSecurityConfig的configure方法中添加会话管理配置:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/home", "/join", "/css/**", "/*.ico", "/error").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/") .failureUrl("/login") .usernameParameter("email") .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/login") .invalidateHttpSession(true) .and() // 新增会话配置 .sessionManagement() // 仅在需要时创建会话,匿名访问静态资源、登录页时不创建会话 .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 登录后迁移会话,防御会话固定攻击 .sessionFixation().migrateSession(); }
需要引入的对应依赖:
import org.springframework.security.config.http.SessionCreationPolicy;
注意:如果注册后仍希望走跳转登录页的逻辑,只需要实现第1点即可,注册接口最后返回
redirect:/login,已完成认证的用户会被控制器逻辑自动重定向到首页。
内容的提问来源于stack exchange,提问作者김병수
相关产品推荐
相关产品推荐

