今日在SpringBoot项目中使用 Spring Security ,登录时发现报500错,报错信息如下:
There is no PasswordEncoder mapped for the id "null"
我接着查找了前端页面上,发现密码框的name属性确实指定的是 password ,并没有出错。这是怎么回事呢?
于是就上网百度,发现这是由于Spring security5中新增加了加密方式,并把原有的spring security的密码存储格式改了。
去官网查找得知,修改后的密码存储格式为:
{id}encodedPassword
于是大概就明白了程序出错的原因: 前端传过来密码后,程序会查找被 花括号"{}"包括起来的id ,以此来确定后面的密码怎么进行加密,而我们在前面并没有按该格式进行处理,这就导致找不到id,就报错了。
明白了报错的原因,就好解决了, 我们只需要对前端传过来的密码进行某种方式加密,就可以了,而官方推荐的是使用bcrypt的加密方式。解决办法如下:
在Securty配置类SecurtyConfig(继承 WebSecurityConfigurerAdapter)中修改 配置即可。
- @EnableWebSecurity
- public class SecurtyConfig extends WebSecurityConfigurerAdapter {
- /**
- * 自定义配置
- *
- * @param http
- * @throws Exception
- */
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- .antMatchers("/css/**", "/js/**", "/fonts/**", "/index").permitAll() //都可以访问
- .antMatchers("/users/**").hasRole("ADMIN") //需要相应的角色才能访问
- .and()
- .formLogin() //基于Form表单登录验证
- .loginPage("/login").failureUrl("/login-error"); //自定义登录界面
- }
-
- /**
- * 认证信息管理
- * spring5中摒弃了原有的密码存储格式,官方把spring security的密码存储格式改了
- *
- * @param auth
- * @throws Exception
- */
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication() //认证信息存储到内存中
- .passwordEncoder(passwordEncoder())
- .withUser("user").password(passwordEncoder().encode("123456")).roles("ADMIN");
- }
-
- private PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
- }
主要是需要对 密码进行加密操作,定义的 passwordEncoder() 方法返回一个 BCryptPasswordEncoder对象,对上面的密码进行加密。这样就解决了该问题。
另外 还有一个也可以解决.
- @Bean
- public static PasswordEncoder passwordEncoder(){
- return NoOpPasswordEncoder.getInstance();
- }
该方法已经过时,不建议使用。