问题描述
SpringBoot升级到了2.0之后的版本,Security也由原来的版本4升级到了5
使用WebSecurityConfigurerAdapter继承重置方法
protected void configure(AuthenticationManagerBuilder auth) throws Exception { //inMemoryAuthentication 从内存中获取 auth.inMemoryAuthentication().withUser("user1").password("123456").roles("USER"); }
此时
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
在Spring Security中密码的存储格式是“{id}…………”。前面的id是加密方式,id可以是bcrypt、sha256等,后面跟着的是加密后的密码。也就是说,程序拿到传过来的密码的时候,会首先查找被“{”和“}”包括起来的id,来确定后面的密码是被怎么样加密的,如果找不到就认为id是null。这也就是为什么我们的程序会报错:There is no PasswordEncoder mapped for the id “null”。官方文档举的例子中是各种加密方式针对同一密码加密后的存储形式,原始密码都是“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
方式一、增加具体实例
内存
protected void configure(AuthenticationManagerBuilder auth) throws Exception { //inMemoryAuthentication 从内存中获取 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("user1").password(new BCryptPasswordEncoder().encode("123456")).roles("USER"); }
在inMemoryAuthentication()后面多了".passwordEncoder(new BCryptPasswordEncoder())",相当于登陆时用BCrypt加密方式对用户密码进行处理。以前的".password("123456")" 变成了 ".password(new BCryptPasswordEncoder().encode("123456"))" ,这相当于对内存中的密码进行Bcrypt编码加密。比对时一致,说明密码正确,允许登陆。
数据库
如果是注入userDetailsService
//注入userDetailsService的实现类 auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
如果你用的是在数据库中存储用户名和密码,那么一般是要在用户注册时就使用BCrypt编码将用户密码加密处理后存储在数据库中。并且修改configure()方法,加入".passwordEncoder(new BCryptPasswordEncoder())",保证用户登录时使用bcrypt对密码进行处理再与数据库中的密码比对。
没有加密方式的
protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()) .withUser("admin").password("123456").roles("USER", "ADMIN"); }
如果配置了spring security oauth2
public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("client").secret("{noop}secret") .authorizedGrantTypes("client_credentials", "password", "refresh_token").scopes("all"); }