Springboot 安全:登录时密码不匹配

jac*_*abe 6 java security encryption spring spring-boot

我正在使用 BCryptPasswordEncoder 来加密用户注册和登录。

注册部分工作正常,它使用密码将新用户放入数据库,例如:

 '$2a$10$aUk/26idLhSaNmhNRTRejd03FnxxLxv6X0Uo0P4PcA4mbyy.
Run Code Online (Sandbox Code Playgroud)

当我登录时,输入的用户名匹配,我成功地从存储库中找到了一个用户。

然后我被告知用户名或密码错误。当我从程序中删除此加密时,它工作正常。所以基本上我在比较加密密码时做错了什么。

这是我的 UserDetailsS​​ervice 实现逻辑:

 public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {

        System.out.println(username);

        User user = userRepository.findByUsername(username);
        System.out.println(user.getPassword());

        if (user.getUsername().isEmpty()) {
            throw new UsernameNotFoundException(
                    "No user found with username: "+ username);
        }
        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;
        return  new org.springframework.security.core.userdetails.User
                (user.getUsername(),
                        user.getPassword().toLowerCase(), enabled, accountNonExpired,
                        credentialsNonExpired, accountNonLocked,
                        getAuthorities(Arrays.asList("ROLE_USER")));
    }

    private static List<GrantedAuthority> getAuthorities (List<String> roles) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
Run Code Online (Sandbox Code Playgroud)

我还在网络安全文件中设置了 bean:

  @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }


@Bean
public PasswordEncoder passwordEncoder(){
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    return encoder;
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?谢谢。

小智 6

除非您设置了非默认配置,否则 BCryptPasswordEncoder 应该将您的用户密码保存到加密的数据库中(它看起来运行正常)。您不应该调用#toLowerCase()加密密码,因为它完全改变了加密。

发布的代码似乎没有做任何比较。

如果您使用手动方式检查密码是否匹配,则应改用BCryptPasswordEncoder.matches 方法。它需要一个未加密的密码,然后是一个加盐哈希(加密密码),然后通过布尔返回值告诉您它们是否相等。