1. 程式人生 > 實用技巧 >SpringBoot2.x整合Security5(解決 There is no PasswordEncoder mapped for the id "null")

SpringBoot2.x整合Security5(解決 There is no PasswordEncoder mapped for the id "null")

問題描述

  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");
}