我很久没能解决这个问题,看了很多东西,还是不明白。
一般来说,我有一个用户注册表单(Thymeleaf),其中的数据传输到控制器,然后对密码进行哈希处理,并通过 JPA 将数据发送到数据库。
但是
当我尝试登录时,我的授权不起作用,据称是密码错误。
同时,如果我在某个网站上对密码进行哈希处理并手动将其输入到数据库中,那么我可以稍后登录。
也就是说,如果手动将哈希值输入数据库,那么我可以登录。如果通过我的应用程序注册,那么我将无法登录。
来自生成器站点的哈希值是使用一种版本的算法获得的,而我的应用程序生成的哈希值是使用不同版本的。因此,我不明白如果整个应用程序只有一个 PasswordEncoder bean 会怎么样。
来自生成器站点的哈希值:
$2y$10$/mZ5HhyfMTml2xj0HYEX0uQfFgHDnsdJ3IhX0pReHUTRVSDuoqAPO
我的应用程序生成的哈希:
$2a$10$2U3MnmqMomhwWQpju1kuy.muBr7TPivlb.wn7XFilMAPJXlwaPx4。
安全配置
@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;
}
}
注册表控制器
@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";
}
}
我尝试使用这个:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(BCryptVersion.$2Y);
}
并尝试了 SHA-256,但效果相同。注册后无法登录。
另外,我尝试使用这个方法:
@Bean
@Autowired
public AuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(passwordEncoder);
return authProvider;
}
但是一样。
问题解决了,真是太愚蠢了。在
Spring Security TRACE
我看到了user disabled
。