网站首页 > 技术文章 正文
Spring Security填坑: Encoded password does not look like BCrypt
btikc 2024-09-25 15:17:30 技术文章 20 ℃ 0 评论一、前言背景:
简单的说一下吧,我所使用的spring security版本是5.4.2,在写登录逻辑的时候,老是报:Encoded password does not look like BCrypt,但是我明明记得数据库里面的字段是用BCryptPasswordEncoder这个类的encode方法加密生成的呀,很确定就是BCrypt类型,感觉没毛病,但就是报这个错,也上网上找了好多文章,有的是写成了用户名导致的,有的说是数据库密码字符串前面需要加加密类型,不一而足,但是我这情况还不一样,有时候真是给自己蠢哭了,留在结尾吧。。
二、意外问题解决
不过就在debug代码的过程中,明白了security关于密码加密的逻辑,简单介绍一下,这就不得不介绍一下密码加密工厂类PasswordEncoderFactories,它里面有这样一个静态方法
public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new LdapShaPasswordEncoder());
encoders.put("MD4", new Md4PasswordEncoder());
encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
集中定义了好多加密算法,默认就是bcrypt类型,假设你已经对spring security有一定了解,且自己实现了UserDetailsService接口,最终会在DaoAuthenticationProvider这个类的这个方法
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (authentication.getCredentials() == null) {
this.logger.debug("Failed to authenticate since no credentials provided");
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
} else {
String presentedPassword = authentication.getCredentials().toString();
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
this.logger.debug("Failed to authenticate since password does not match stored value");
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
}
}
里面进行密码校验,passwordEncoder就是你项目里面定义的密码加密类型,如果你没有显式定义,框架会默认调用上面提到的密码加密工厂类PasswordEncoderFactories生成的加密类型DelegatingPasswordEncoder选择符合加密类型的加密算法实现类,用其matches方法进行密码校验,如果你已经在你的配置类里面显示的声明了加密实现类,如
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
那么在DaoAuthenticationProvider这个类的密码校验方法就会直接进到BCryptPasswordEncoder的matches方法进行校验,而不再进行加密类型的选择,这里要注意显式声明与否时对应的数据库里面密码的字符串格式。
具体就是当显示声明密码加密类型后,数据库里面的密码字段直接存储加密后的字符串即可,例如:我的密码是pass,加密后直接存储就是:$2a$10$yhKm0EE.dobwxXrDqMvSmuMTGcOp6/zHOQZAwpNkwq2tcg8Ze/7oG;当未显式声明密码加密类型时,数据库里面的密码字段的字符串存储格式为:{加密类型}+加密后的字符串,例如我用BCryptPasswordEncoder加密的密码,那么就是:{bcrypt}$2a$10$yhKm0EE.dobwxXrDqMvSmuMTGcOp6/zHOQZAwpNkwq2tcg8Ze/7oG
注意:这两种不能混用、而且必须、也仅能二选其一
三、我的问题最后调试发现是数据库密码字段长度设置小了,因为我用的是mysql5.7,而5.7的mode是STRICT_TRANS_TABLES,也就是严格模式。超过长度被截取了,所以再看看BCryptPasswordEncoder这个类的正则校验
this.BCRYPT_PATTERN = Pattern.compile("\\A\\$2(a|y|b)?\\$(\\d\\d)\\$[./0-9A-Za-z]{53}");
除了前面不啦不啦一些校验后面还有53个字符呢,所以。。。。
猜你喜欢
- 2024-09-25 SpringBoot集成Spring Security入门体验
- 2024-09-25 Spring Boot Actuator的端点都怎么用?咱用事实说话
- 2024-09-25 Spring Security-2-表单认证 spring security关闭表单登陆
- 2024-09-25 自营性电商项目④ 自营式电商平台的主要优势在于
- 2024-09-25 微服务架构系列之–前后端分离 JWT认证机制
- 2024-09-25 SpringBoot整合SpringSecurity和JWT实现mymes认证和授权(一)
- 2024-09-25 跟我学spring security系列文章第一章 实现一个基本的登入
- 2024-09-25 SpringBoot集成Spring Security springboot集成Elasticsearch
- 2024-09-25 Spring Security身份验证详细介绍
- 2024-09-25 如何使用JWT和Spring Security保护REST API,你会多少?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)