Spring Security – There is no PasswordEncoder mapped for the id “null”

Send a GET request with username and password, but hits the password encoder error?

Tested

  • Spring Boot 2.1.2.RELEASE
  • 5.1.3.RELEASE

$ curl localhost:8080/books -u user:password

{
	"timestamp":"2019-02-22T15:03:49.322+0000",
	"status":500,
	"error":"Internal Server Error",
	"message":"There is no PasswordEncoder mapped for the id \"null\"",
	"path":"/books"
}

errors in logs


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

Here is the configuration.

SpringSecurityConfig.java

package com.mkyong.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

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

    }

}

Solution

Prior to Spring Security 5.0 the default PasswordEncoder was NoOpPasswordEncoder which required plain text passwords. In Spring Security 5, the default is DelegatingPasswordEncoder, which required Password Storage Format.

Read this and this

Solution 1 – Add password storage format, for plain text, add {noop}

SpringSecurityConfig.java

package com.mkyong.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

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

    }

}

Solution 2User.withDefaultPasswordEncoder() for UserDetailsService

SpringSecurityConfig.java

package com.mkyong.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @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;

    }

}

References

14 comments on “Spring Security – There is no PasswordEncoder mapped for the id “null”

  1. I am facing this kind of problem but using Spring Boot 2.1.6, I really cant find whats the problem.

    I have on my controller:


    import org.springframework.security.authentication.AuthenticationManager;

    @Autowired
    AuthenticationManager authenticationManager;

    @PostMapping(“/signin”)
    public ResponseEntity signin(@RequestBody AuthenticationRequest data) {
    try {
    String email = data.getEmail();
    String password = data.getSenha();
    // Problem occurs here
    authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password ));

    String token = jwtTokenProvider.createToken(email,
    this.usuarioRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException(“Usuário com email ” + email + ” não encontrado”)).roles());

    Map model = new HashMap();
    model.put(“email”, email);
    model.put(“token”, token);
    return ok(model);
    } catch (AuthenticationException e) {
    e.printStackTrace();
    throw new BadCredentialsException(“Inválido email/senha fornecido”);
    }
    }

    My WebSecurity:
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    JwtTokenProvider jwtTokenProvider;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http
    .httpBasic().disable()
    .csrf().disable()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and()
    .authorizeRequests()
    .antMatchers(HttpMethod.POST, “/api/usuario/**”).permitAll()
    .antMatchers(HttpMethod.DELETE, “/api/usuario/**”).hasRole(“ADMIN”)
    .antMatchers(HttpMethod.GET, “/api/empresa/**”).hasRole(“USER”)
    .antMatchers(HttpMethod.POST, “/api/empresa/**”).hasRole(“USER”)
    .antMatchers(HttpMethod.PUT, “/api/empresa/**”).hasRole(“USER”)
    .antMatchers(HttpMethod.DELETE, “/api/empresa/**”).hasRole(“USER”)
    .anyRequest().authenticated()
    .and()
    .apply(new JwtSecurityConfigurer(jwtTokenProvider));
    }

    }

    If you can point me something I can do I would appreciate it very much.

  2. Unfortunately withDefaultPasswordEncoder is now deprecated.
    This works without deprecation:
    ´´´
    @Bean
    public UserDetailsService userDetailsService() {
    PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
    UserDetails user = User.withUsername(“user”)
    .password(encoder.encode(“user”))
    .roles(“USER”).build();
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(user);
    return manager;

    }
    ´´´

Leave a Comment

Your email address will not be published. Required fields are marked *