Spring Security自定义登录始终返回login?error问题求助
Hey there! Let's figure out why your authentication keeps landing on login?error no matter what credentials you enter. I've spotted a couple of critical issues in your code that are causing this problem:
1. Missing name attributes on login form inputs
Spring Security's form login expects the username and password fields to have name="username" and name="password" respectively. Right now your login.html inputs only have id attributes—so when you submit the form, the credentials aren't being sent to the server correctly.
Fix your login.html form inputs:
<form th:action="@{/login}" method="post"> <div class="container"> <div class="alert alert-danger" th:if="${param.error}"> Invalid username and password. </div> <div class="form-group row"> <label for="login" class="col-sm-2 col-form-label">Логин</label> <div class="col-sm-10" style="width: 100%; max-width: 500px;"> <!-- Add name="username" here --> <input type="text" class="form-control" id="login" name="username" placeholder="Логин"/> </div> </div> <div class="form-group row"> <label for="password" class="col-sm-2 col-form-label">Пароль</label> <div class="col-sm-10" style="width: 100%; max-width: 500px;"> <!-- Add name="password" here --> <input type="password" class="form-control" id="password" name="password" placeholder="Пароль"/> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Войти</button> </div> </div> </div> </form>
2. No password encoder configured (critical for Spring Security 5+)
Starting from Spring Security 5, plain-text passwords are blocked by default unless you explicitly configure a password encoder. Your in-memory user uses a plain-text password "123" without any encoding, which causes authentication to fail silently.
Update your WebSecurityConfig to add a password encoder:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // Add a password encoder bean (use NoOp only for testing!) @Bean public PasswordEncoder passwordEncoder() { // ⚠️ WARNING: NoOpPasswordEncoder is insecure for production! return NoOpPasswordEncoder.getInstance(); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated(); http .formLogin() .loginPage("/login") .permitAll(); } @Configuration protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Override public void init(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .passwordEncoder(passwordEncoder) // Attach the encoder to your auth setup .withUser("qwerty").password("123").roles("USER"); // Use a standard role name like "USER" } } }
💡 Production Note: Replace
NoOpPasswordEncoderwith a secure encoder likeBCryptPasswordEncoderfor live applications:@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }You'll need to store encoded passwords (generate them via
passwordEncoder.encode("123")instead of plain text).
3. Minor: Role naming convention
While not the root cause, it's best practice to use standard role names like "USER" or "ADMIN" instead of "ROLE". Spring Security automatically adds the ROLE_ prefix internally, so roles("USER") translates to ROLE_USER.
After making these changes, restart your application and try logging in with qwerty / 123—it should authenticate successfully now!
内容的提问来源于stack exchange,提问作者Бахтияр Сейдахметов

