Search code examples
javahibernatespring-securityspring-data-jpaspring-data

Passwords for registration and login of BCryptPasswordEncoder in Spring Security 6 do not match


I haven't been able to solve the problem for a long time, I've read a lot of things, I still don't understand.

In general, I have a user registration form (Thymeleaf), data from it is transmitted to the controller, then the password is hashed and the data is sent to the database via JPA.

but

When I try to log in, my authorization does not work, allegedly the wrong password.

At the same time, if I hash the password on some website and manually enter it into the database, then I can log in later.

That is, if the hash is entered manually into the database, then I can log in. If the registration goes through my application, then I will not be able to log in.

The hash from the generator site is obtained with one version of the algorithm, and the hash that my application generates with a different version. Therefore, I do not understand how it is if I have only one PasswordEncoder bean for the entire application.

Hash from the generator site:

$2y$10$/mZ5HhyfMTml2xj0HYEX0uQfFgHDnsdJ3IhX0pReHUTRVSDuoqAPO

Hash generated by my application:

$2a$10$2U3MnmqMomhwWQpju1kuy.muBr7TPivlb.wn7XFilMAPJXlwaPx4.

SecurityConfig

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserService();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/", "/css/**", "/js/**", "/images/**", "/candidate/**", "/setup/**").permitAll()
            .requestMatchers("/chat/**").hasAnyRole("ADMIN","HEAD","USER")
            .requestMatchers("/users/**").hasAnyRole("ADMIN","HEAD")
            .requestMatchers("/admin/**").hasAnyRole("ADMIN")
            .anyRequest().authenticated()
        ).formLogin((form) -> form
            .loginPage("/login")
            .failureUrl("/login?error=true")
            .defaultSuccessUrl("/cards", true)
            .permitAll()
        ).logout((logout) -> logout
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login")
            .deleteCookies("JSESSIONID")
            .invalidateHttpSession(true)
            .clearAuthentication(true)
        )
        .build();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

}

Registration Form Controller

@Controller
@RequestMapping("/setup")
class SetupController {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping("/create")
    public String setupUser(User user) {
        try {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            userService.save(user);
        } catch(Exception e) {
            System.out.println(e);
            return "redirect:/setup?error=true";
        }
        return "redirect:/login";
    }
}

I tried to use this:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(BCryptVersion.$2Y);
}

and tried SHA-256, but it works the same. I can't login after registration.

Also, I tried to use this method:

@Bean
@Autowired
public AuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(userDetailsService);
    provider.setPasswordEncoder(passwordEncoder);
    return authProvider;
}

but the same.


Solution

  • The problem was solved and it was damn stupid. In the Spring Security TRACE I saw that user disabled.