Доброе утро, я столкнулся с проблемой при входе в приложение, которое использует Spring Security. Каждый раз, когда я пытаюсь войти в систему (даже если имя пользователя и пароль верны), приложение перенаправляет меня на URL ошибки (в моем случае это: / login? Error = true). Пароли зашифрованы с помощью BCrypt, и я использую MySQL базу данных для их хранения.
Приложение основано на коде из Spring в действии 5: https://github.com/habuma/spring-in-action-5-samples/tree/master/ch04/tacos
Мой код:
Класс пользователя
@Entity
@Data
@NoArgsConstructor
@Table(name = "Users")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String email;
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
Конфигурация безопасности
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Qualifier("userService")
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/calendar")
.hasRole("USER")
.antMatchers("/","/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/calendar")
.failureUrl("/login?error=true")
.and()
.logout()
.logoutSuccessUrl("/");
}
}
Сервис пользователя
@Service
public class UserService implements UserDetailsService {
private UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository){
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if(user != null){
return user;
}
throw new UsernameNotFoundException("Username not found: "+username);
}
}
Контроллер
@Controller
@RequestMapping("/register")
public class UserController {
private UserRepository userRepository;
private PasswordEncoder passwordEncoder;
@Autowired
public UserController(UserRepository userRepository, PasswordEncoder passwordEncoder){
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@ModelAttribute
public void calendar(Model model){
model.addAttribute("user", new User());
}
@GetMapping
public String register(){
return "register";
}
@PostMapping
public String addUser(@ModelAttribute User user){
User newUser = new User(user.getUsername(),passwordEncoder.encode(user.getPassword()),user.getEmail());
userRepository.save(newUser);
return "redirect:/login";
}
}
Форма входа (Thymeleaf)
<form th:method="POST" th:action="@{/login}">
<div class="formInputs">
<label for="username">Username</label>
<input id="username" name="username" type="text">
</div>
<div class="formInputs">
<label for="password">Password</label>
<input id="password" name="password" type="password">
</div>
<div style="clear: both"></div>
<input type="submit" value="Log in">
</form>
Форма регистрации
<form method="POST" th:action="@{/register}" th:object="${user}">
<div class="formInputs">
<label for="username">Username</label>
<input id="username" type="text" th:field="*{username}">
</div>
<div class="formInputs">
<label for="password">Password</label>
<input id="password" type="password" th:field="*{password}">
</div>
<div class="formInputs">
<label for="email">Email</label>
<input id="email" type="email" th:field="*{email}">
</div>
<div style="clear: both"></div>
<input type="submit" value="Register">
<input type="reset" value="Reset">
</form>
Если кто-то может помочь мне найти решение, я был бы признателен, заранее спасибо.