You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Security:Encoded password does not look like BCrypt致登录失败求助

问题排查:Spring Boot JWT登录返回401及“Encoded password does not look like BCrypt”错误

核心问题分析

报错“Encoded password does not look like BCrypt”说明Spring Security认证时,获取到的用户密码并非合法的BCrypt加密格式,或是加密、认证环节使用的密码编码器不一致。结合401错误,优先排查以下关键点:

1. 检查UserDetailsServiceImpl实现(最可能的根因)

你未提供该类代码,但它是Spring Security加载用户信息的核心组件,必须满足:

  • 从数据库查询的用户密码是BCrypt加密后的字符串(以$2a$或$2b$开头)
  • 返回的UserDetails对象(如org.springframework.security.core.userdetails.User)中的密码字段未被二次修改(比如转成明文)
  • 未手动指定其他密码编码器,必须使用Spring容器中定义的BCryptPasswordEncoder Bean

正确实现示例:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.getByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
        // 直接返回数据库存储的BCrypt加密密码,不做任何修改
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                mapRolesToAuthorities(user.getRoles())
        );
    }

    private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Set<Rol> roles) {
        return roles.stream()
                .map(rol -> new SimpleGrantedAuthority(rol.getRolName().name()))
                .collect(Collectors.toList());
    }
}

2. 确保密码编码器全局一致性

  • 检查项目中是否存在多个PasswordEncoder Bean定义,比如明文编码器,这会导致加密、认证规则不统一
  • 确认AuthController注入的passwordEncoder与MainSecurity中定义的BCryptPasswordEncoder是同一个Bean,未被其他组件覆盖

3. 修复创建用户代码的语法错误

你的AuthController存在明显笔误:

// 错误:缺少括号,应为getUsername()
if(userService.existsByUsername(newUser.getUsername))

即便创建用户环节正常,也要确认:

  • NewUser类的getPassword()方法能正确返回前端传入的密码
  • 数据库中存储的用户密码是BCrypt格式(60位左右字符串,以$2a$开头)

4. 排查JwtEntryPoint的commence方法

报错提到该方法执行失败,大概率是方法内部存在异常(比如响应写入错误)。可暂时简化该方法,确保正常输出错误信息:

@Component
public class JwtEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "认证失败: " + authException.getMessage());
    }
}

验证步骤

  1. 重新创建用户,查看数据库密码字段是否为BCrypt格式
  2. 在UserDetailsServiceImpl的loadUserByUsername方法中添加日志,打印加载到的用户密码,确认是加密后的字符串
  3. 确认认证使用的AuthenticationManager是MainSecurity中配置的Bean,无自定义逻辑干扰

内容的提问来源于stack exchange,提问作者tsu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:35:18