绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
There is no PasswordEncoder . the id “null”异常解决办法
2020-03-03 16:54:10

There is no PasswordEncoder mapped for the id “null”异常解决办法

一. 问题描述

Spring security 5.0中新增了多种加密方式,也改变了默认的密码格式.

我们来看一下官方文档:

The general format for a password is:

{id}encodedPassword
Such that id is an identifier used to look up which PasswordEncoder should be used and encodedPassword is the original encoded password for the selected PasswordEncoder. The id must be at the beginning of the password, start with { and end with }. If the id cannot be found, the id will be null. For example, the following might be a list of passwords encoded using different id. All of the original passwords are "password".

{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG 
{noop}password 
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc 
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=  
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0

这段话的意思是说,现如今Spring Security中密码的存储格式是“{id}…………”.前面的id是加密方式,id可以是bcrypt、sha256等,后面跟着的是加密后的密码.也就是说,程序拿到传过来的密码的时候,会首先查找被“{”和“}”包括起来的id,来确定后面的密码是被怎么样加密的,如果找不到就认为id是null.这也就是为什么我们的程序会报错:There is no PasswordEncoder mapped for the id “null”.官方文档举的例子中是各种加密方式针对同一密码加密后的存储形式,原始密码都是“password”.

二. 解决办法

需要修改一下configure中的代码,我们要将前端传过来的密码进行某种方式加密,Spring Security 官方推荐的是使用bcrypt加密方式.

1. 内存中存取密码的修改方式

修改后是这样的:

protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  //inMemoryAuthentication 从内存中获取
  auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("user1").password(new BCryptPasswordEncoder().encode("123")).roles("USER");
}

inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())",这相当于登陆时用BCrypt加密方式对用户密码进行处理.以前的".password("123")" 变成了 ".password(new BCryptPasswordEncoder().encode("123"))",这相当于对内存中的密码进行Bcrypt编码加密.如果比对时一致,说明密码正确,才允许登陆.

2. 在数据库中存取密码的修改方式

如果你用的是在数据库中存储用户名和密码,那么一般是要在用户注册时就使用BCrypt编码将用户密码加密处理后存储在数据库中,并且修改configure()方法,加入".passwordEncoder(new BCryptPasswordEncoder())",保证用户登录时使用bcrypt对密码进行处理再与数据库中的密码比对.如下:

//注入userDetailsService的实现类
auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());

分享好友

分享这个小栈给你的朋友们,一起进步吧。

Spring Boot
创建时间:2020-06-22 17:22:00
SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • duanhao
    栈主

小栈成员

查看更多
  • ?
  • zander
  • 凉茶cooltea
戳我,来吐槽~