Spring Security多密码编码类型使用疑问:编码选择逻辑解析
Spring Security多密码编码机制答疑
针对你提到的用户名/密码注册场景,结合给出的配置代码,解答如下:
问题1:调用PasswordEncoder.encode(password)时,系统如何确定编码类型?
你配置的是DelegatingPasswordEncoder,在构造它时传入的第一个参数"bcrypt"就是默认编码器标识。当调用encode(password)方法时,DelegatingPasswordEncoder会直接使用这个默认对应的编码器(也就是你配置的BCryptPasswordEncoder)来对密码进行编码,最终生成的密码字符串会带上{bcrypt}前缀,比如{bcrypt}$2a$10$...。
问题2:Spring如何自动从已配置的编码类型中选择合适的实现?
DelegatingPasswordEncoder的核心作用就是支持多密码编码共存,它的自动选择逻辑体现在密码验证阶段(而非注册阶段):
- 当验证密码时,它会先解析存储的密码字符串的前缀(比如
{noop}、{scrypt}),这个前缀就是你在encodersMap中定义的键值。 - 根据前缀匹配到对应的
PasswordEncoder实现,再用该编码器完成密码校验。 - 注册阶段始终使用构造
DelegatingPasswordEncoder时指定的默认编码器,只有验证时才会根据密码前缀动态选择编码器。
你提供的配置代码整理:
public PasswordEncoder passwordEncoder() { Map<String, PasswordEncoder> encoders = new HashMap<>(); encoders.put("noop", NoOpPasswordEncoder.getInstance()); encoders.put("bcrypt", new BCryptPasswordEncoder()); encoders.put("scrypt", new SCryptPasswordEncoder()); return new DelegatingPasswordEncoder("bcrypt", encoders); } private final PasswordEncoder passwordEncoder; public UserAccount register(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("firstName") String firstName, @RequestParam("lastName") String lastName) { UserAccount userAccount = new UserAccount(); userAccount.setUsername(username); userAccount.setPassword(passwordEncoder.encode(password)); return userAccountRepository.save(userAccount); }
内容的提问来源于stack exchange,提问作者Moulina Mary A
相关产品推荐
相关产品推荐

