解决记录之十一——Spring安全及java.lang.IllegalArgumentException:There is no PasswordEncoder mapped for the id错误

使用说明:

1、在使用1.X版本的Spring-boot-starter-parent ,如果出现Exception parsing document错误,通常是因为集成的thymeleaf和thymeleaf-layout-dialect版本较老,需要排除老版本换成新版本;2、与thymeleaf集成时,需要在pom.xml文件中引入

<dependency>
            <groupId>org.thymeleaf.extrasgroupId>
            <artifactId>thymeleaf-extras-springsecurity5artifactId>
        dependency>

;在html文件头部引入



3、Spring Security默认会提供登录页面和登录逻辑处理。如果使用定制的登录页面,使用loginPage可以定制,GET方法跳转到登录页面,POST方法跳转到登录处理逻辑,两者需要使用相同的URL。

/loginpage GET 跳转到登录页面
/loginpage POST 处理登录逻辑
/loginpage?error GET 重定向的登录失败页面
/loginpage?logout GET 注销成功后的重定向页面

错误

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id “null”

在Spring Security 5.0之前,默认值PasswordEncoderNoOpPasswordEncoder需要纯文本密码。在Spring Security 5中,默认值为DelegatingPasswordEncoder,这需要密码存储格式

解决方案1:- 添加密码存储格式,对于纯文本,添加{noop}

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
     
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}password").roles("USER")
                .and()
                .withUser("admin").password("{noop}password").roles("ADMIN");

    }

}

解决方案2:为UserDetailsService 使用User.withDefaultPasswordEncoder()

@Bean
    public UserDetailsService userDetailsService() {
        //注释部分的代码为弃用的方式
        //User.UserBuilder users = User.withDefaultPasswordEncoder();
        //InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
           //manager.createUser(users.username("user").password("password").roles("USER").build());
        //manager.createUser(users.username("admin").password("password").roles("USER", "ADMIN").build());
        //return manager;
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user1")
                .password(encoder.encode("pwd1"))
                .roles("VIP1", "VIP2").build());
        manager.createUser(User.withUsername("user2")
                .password(encoder.encode("pwd2"))
                .roles("VIP3", "VIP2").build());
        return manager;
    }

参考文档:https://www.thymeleaf.org/doc/articles/springsecurity.html

增加数据库密码验证的例子:https://juejin.im/post/5c191e425188252dcb310898

整合Security JWT前后分离 认证授权:https://www.jianshu.com/p/ca4cebefd1cc

源码:https://github.com/Lswx2017/securitydemo.git

你可能感兴趣的:(后端开发)