Вход в Spring Security не удается, несмотря на правильное имя пользователя и пароль - PullRequest
0 голосов
/ 10 апреля 2020

Доброе утро, я столкнулся с проблемой при входе в приложение, которое использует 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>

Если кто-то может помочь мне найти решение, я был бы признателен, заранее спасибо.

1 Ответ

0 голосов
/ 10 апреля 2020

Убедитесь, что ваш пользователь возвращает enabled = true, а также isAccountNonExpired = true (и все остальные, например, isAccountNonLocked). Также верните empty list of authorities, не ноль.

В противном случае Spring Security будет рассматривать вашего пользователя как отключенного / заблокированного / любого другого и не позволит вам войти в систему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...