Answer the question
In order to leave comments, you need to log in
Why can't login spring rest jwt?
Unable to log in, although registration is successful. Googled and someone wrote that the problem is that the password that came is not hashed, I try to hash it still does not work. I don't understand what the problem is. An exception is thrown and a 401 error is basically here:
authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
username,
password
)
);
@RestController
@RequestMapping("/api/auth")
public class LoginController {
@Autowired
AuthenticationManager authenticationManager;
Logger logger = LoggerFactory.getLogger(LoginController.class);
@Autowired
UserRepository userRepository;
@Autowired
RoleRepository roleRepository;
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
JwtTokenProvider tokenProvider;
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
String username = loginRequest.getUserName();
String password = passwordEncoder.encode(loginRequest.getPassword());
Authentication authentication;
try {
authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
username,
password
)
);
} catch (AuthenticationException e) {
logger.error("Invalid username/password supplied");
throw new BadCredentialsException("Invalid username/password supplied");
}
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
@PostMapping("/signup")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
if (userRepository.existsByUserName(signUpRequest.getUserName())) {
return new ResponseEntity(new ApiResponse(false, "Username is already taken!"),
HttpStatus.BAD_REQUEST);
}
// Creating user's account
Role userRole = roleRepository.findByRole(String.valueOf(RoleName.ROLE_USER))
.orElseThrow(() -> new AppException("User Role not set."));
User user = new User(signUpRequest.getUserName(), signUpRequest.getPassword(),
signUpRequest.getName(), signUpRequest.getLastName(), signUpRequest.getMiddleName(), Collections.singleton(userRole));
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setRoles(Collections.singleton(userRole));
User result = userRepository.save(user);
URI location = ServletUriComponentsBuilder
.fromCurrentContextPath().path("/users/{username}")
.buildAndExpand(result.getUserName()).toUri();
return ResponseEntity.created(location).body(new ApiResponse(true, "User registered successfully"));
}
}
Answer the question
In order to leave comments, you need to log in
I solved the problem, it turns out that when I passed an object in the UserDetailsService method in the loadUserByUsername method, which was created based on UserDetails, I forgot to return objects in the username and password getters, and there is no need to send a hashed password. Everything is working.
Method:
@Override
@Transactional
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userRepository.findByUserName(userName)
.orElseThrow(() ->
new UsernameNotFoundException("User not found with username: " + userName)
);
UserPrincipal userPrincipal = UserPrincipal.create(user);
logger.info("user with name: {} succesfully loaded", userPrincipal.getUsername());
return userPrincipal;
}
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
public class UserPrincipal implements UserDetails {
static Logger logger = LoggerFactory.getLogger(UserPrincipal.class);
private Long id;
private String name;
private String username;
private String lastname;
private String middlename;
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserPrincipal(Long id, String username, String name, String password, String lastname, String middlename, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.name = name;
this.username = username;
this.lastname = lastname;
this.middlename = middlename;
this.password = password;
this.authorities = authorities;
}
public static UserPrincipal create(User user) {
logger.info(user.toString());
List<GrantedAuthority> authorities = user.getRoles().stream().map(role ->
new SimpleGrantedAuthority(role.getRole())
).collect(Collectors.toList());
return new UserPrincipal(
user.getId(),
user.getUserName(),
user.getName(),
user.getPassword(),
user.getLastName(),
user.getMiddleName(),
authorities
);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserPrincipal that = (UserPrincipal) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
String username = loginRequest.getUserName();
String password = loginRequest.getPassword();
Authentication authentication;
try {
authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
username,
password
)
);
} catch (AuthenticationException e) {
logger.error("Invalid username/password supplied");
throw new BadCredentialsException("Invalid username/password supplied");
}
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question