I am using JWT with spring boot to secure my API The Users are in database and ihave an exception when i call this API
type here
List<Professionnel> professionnels = Stream.of(
new Professionnel("email1@gmail.com", "111", "06497555555", "resp1", "soc1", "adresse1", "93500", "vill1", "sir1"),
new Professionnel("email1@gmail.com","222", "06598666666", "resp2", "soc2", "adresse2", "75000", "vill2", "sir2"),
new Professionnel("email3@gmail.com", "333", "06789777777", "resp3", "soc3", "adresse3", "69000", "vill3", "sir3")
).collect(Collectors.toList());
professionnelRepository.saveAll(professionnels);
accountService.addNewRole("USER");
accountService.addNewRole("ADMIN");
accountService.addNewUtilisateur("email11", STATUT_COMPTE.A_ACTIVER, "1234", "1234");
accountService.addNewUtilisateur("email22", STATUT_COMPTE.A_ACTIVER, "1234", "1234");
accountService.addNewUtilisateur("email33", STATUT_COMPTE.A_ACTIVER, "1234", "1234");
accountService.addRoleToUtilisateur("email11", "USER");
accountService.addRoleToUtilisateur("email22", "USER");
accountService.addRoleToUtilisateur("email33", "USER");
accountService.addRoleToUtilisateur("email33", "ADMIN");
departementService.initDepartement();
for the moment I put the passwords in clear not encrypted In the securityFilterChain method I authorize access to the API /auth/login
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.csrf(csrf -> csrf.disable())
.cors(Customizer.withDefaults())
.authorizeHttpRequests(ar->ar.requestMatchers("/auth/login/**").permitAll())
.authorizeHttpRequests(ar->ar.requestMatchers("/swagger-ui/**").permitAll())
.authorizeHttpRequests(ar->ar.requestMatchers("/professionnel/create/**").permitAll())
.authorizeHttpRequests(ar->ar.requestMatchers("/swagger-ui/index.html/**").permitAll())
.authorizeHttpRequests(ar->ar.requestMatchers("/demandeDevis/**").permitAll())
.authorizeHttpRequests(ar -> ar.anyRequest().authenticated())
.userDetailsService(userDetailsServiceImpl)
.oauth2ResourceServer(oa -> oa.jwt(Customizer.withDefaults()))
.build();
}
authentication API
@RestController
**@RequestMapping("/auth")**
public class SecurityControler {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
JwtEncoder jwtEncoder;
/*
@Autowired
PasswordEncoder passwordEncoder;
*/
@GetMapping("/profile")
public Authentication profile(Authentication authentication){
return authentication;
}
**@PostMapping("/login")**
public Map<String,String> login(String username,String password){
username="email11";
password="1234";
Authentication authentication= authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username,password));
Instant instant=Instant.now();
String scope = authentication.getAuthorities().stream().map(aut->aut.getAuthority()).collect(Collectors.joining(" "));
JwtClaimsSet jwtClaimsSet=JwtClaimsSet.builder()
.issuedAt(instant)
.expiresAt(instant.plus(60, ChronoUnit.MINUTES))
.subject(username)
.claim("scope",scope)
.build();
JwtEncoderParameters jwtEncoderParameters=
JwtEncoderParameters.from(
JwsHeader.with(MacAlgorithm.HS512).build(),
jwtClaimsSet
);
String jwt = jwtEncoder.encode(jwtEncoderParameters).getTokenValue();
return Map.of("acess-token",jwt);
}```
And finally here is my serviceUserDetailService
@Service public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired AccountService accountService;
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Utilisateur utilisateur = accountService.loadUtilisateurByUserName(username); String[] roles = utilisateur.getRoles().stream().map(us -> us.getRole()).toArray(String[]::new); if (utilisateur == null) throw new UsernameNotFoundException(String.format("L'utilisaeteur %s n'existe pas ", username)); UserDetails userDetails = User.withUsername(utilisateur.getUsername()) .password(utilisateur.getPassword()) .roles(roles).build();
return userDetails;
} }
Here are the users in the database statut|password|user_id |username| ------+--------+------------------------------------+--------+ 2|1234 |5bed6145-e582-4be2-8135-2f88eb34ca69|email11 | 2|1234 |c67e9cc2-5646-46ac-80d3-3cad2356ec66|email33 | 2|1234 |ff1ee6e4-287b-4db7-b20e-7da4d0b7e24f|email22 |
Here is the call
`POST http://127.0.0.1:4001/auth/login Content-Type: application/x-www-form-urlencoded Content-Length: 29 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.5.13 (Java/17.0.5) Accept-Encoding: br,deflate,gzip,x-gzip
username=email11&password=1234 ` the response is 401 and in debug mode I have this exception There is no PasswordEncoder mapped for the id "null" in
Authentication authentication= authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username,password));
When i add the passwordEncoder like this :
@PostMapping("/login") public Map<String,String> login(String username,String password){
username="email11";
password=passwordEncoder.encode("1234");
// and when i add the users i encode the password like this : accountService.addNewUtilisateur("email11", STATUT_COMPTE.A_ACTIVER, bCryptPasswordEncoder.encode("1234"), bCryptPasswordEncoder.encode("1234"));
i have this exception org.springframework.security.authentication.BadCredentialsException: –