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.
The problem was solved and it was damn stupid. In the Spring Security TRACE
I saw that user disabled
.