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.
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 2 – User.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;
}
}
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;
}
´´´
did it work
me sirvio mucho la primera solucion gracias.
Thanks a lot. I can resolve the same issue with the 1st solution
hi dear mkyong
i need spring 5 security – jwt example without boot.
thanks
the first solution work for me thank for all
gracias!
Thanks man!
Thanks for the solution
Merci beaucoup
Many thanks…
The first solution works for me !!!
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.
Thanks a lot. I got output for the second solution. But I got the same error. when I use the first solution
nice, i get my trouble