I want to create a REST API endpoint, to let users change/update their credentials.
I have a CustomUserDetails:
@Entity
@Table(name="ACCOUNT_USER")
public class CustomUserDetails implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
@NotBlank
@Column(name = "USERNAME", unique=true)
private String username;
@NotBlank
@Column(name = "PASSWORD")
private String password;
@Column(name = "LOCKED")
private boolean locked;
@ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable(name = "USER_ROLE",
joinColumns = @JoinColumn(name = "USER_ID"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
private Set<CustomRole> roles;
public CustomUserDetails(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<GrantedAuthority> authorities) {
this.setUsername(username);
this.setPassword(password);
this.roles = new HashSet<CustomRole>();
for (GrantedAuthority authority: authorities) {
roles.add(new CustomRole(authority.getAuthority()));
}
}
public CustomUserDetails() { // jpa only
}
//setters and getters
}
The Rest controller looks like this:
@SuppressWarnings("rawtypes")
@RequestMapping(value = "/singup", method = RequestMethod.PUT)
public ResponseEntity updateCredentials(@RequestBody CustomUserDetails user, HttpServletResponse response) throws IOException {
logger.debug("Attempting credentials update " + user.getUsername());
try {
authenticateUserAndSetSession(user, response);
} catch(BadCredentialsException ex) {
return SecurityUtils.createCustomResponseEntity(CustomStatusCode.BAD_CREDENTIALS);
}
customUserDetailsService.update(user, newPassword); // where to add this newPassword ?
return SecurityUtils.createCustomResponseEntity(CustomStatusCode.OK);
}
As you can see, there is nop newPassword
field for the CustomUserDetails.
Does it make sense to add this field to this object ? What are other options ? What is the best practice in this case ?