Spring Security自定义登录认证失败:无法从MySQL获取用户
问题解决:Spring Boot Security自定义登录页认证失败(提示找不到空用户)
问题现象
使用自定义登录页结合MySQL实现用户认证时,数据库中已存在的用户登录始终失败,DEBUG日志提示Failed to find user '',认证后持续跳回登录页,无法进入dashboard页面。
问题根源
从日志与代码可定位两个核心问题:
- 登录表单请求方法错误:表单使用
GET方法,而Spring Security的表单认证默认仅处理POST请求的/login接口,GET请求仅会触发登录页跳转,不会将用户名/密码传入认证流程,导致UserDetailsService接收到的用户名为空字符串。 - 用户名参数不匹配:Spring Security默认读取
name="username"的输入框作为登录用户名,但你的表单使用name="email"作为登录标识,且UserDetailsService通过email加载用户,Security未收到正确的用户名参数,因此查询不到用户。
修复步骤
1. 修改登录表单的请求方法与输入框属性
将表单请求方法改为POST,同时将密码输入框的type改为password(符合安全规范):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login Form</title> </head> <body> <div th:if="${successMessage}"> <p th:text="${successMessage}" style="color:green"></p> </div> <form th:action="@{/login}" method="POST"> <input type="text" name="email" placeholder="ENTER EMAIL: " required> <input type="password" name="password" placeholder="ENTER PASSWORD: " required> <button type="submit">LOGIN</button> </form> </body> </html>
2. 在SecurityConfig中指定用户名参数名
在formLogin配置中添加usernameParameter("email"),告知Spring Security使用email作为登录用户名的参数名:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests( authorization -> authorization .requestMatchers("/welcome", "/register", "/login").permitAll() .requestMatchers("/dashboard").authenticated() // 修正原配置中错误的拦截路径 ) .formLogin( login -> login .loginPage("/login") .usernameParameter("email") // 新增:指定用户名参数为email .defaultSuccessUrl("/dashboard", true) .permitAll() ); return http.build(); }
注意:原配置中
.requestMatchers("/welcome/**").authenticated()应为.requestMatchers("/dashboard").authenticated(),否则认证成功后访问dashboard仍会被拦截。
3. 确认密码加密存储
确保用户注册时,密码通过BCryptPasswordEncoder加密后存入数据库,示例UserService代码:
@Service public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; } public void saveUser(User user) { user.setPassword(passwordEncoder.encode(user.getPassword())); // 加密密码后存储 userRepository.save(user); } }
验证修复
重启项目后,使用数据库中已注册的用户登录,日志会显示正确加载用户信息,认证成功后将自动跳转到dashboard页面。
内容的提问来源于stack exchange,提问作者dev7
相关产品推荐
相关产品推荐

