我想创建一个 REST API 端点,以让用户更改/更新他们的凭据。
我有一个自定义用户详细信息:
@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
}
Rest Controller 如下所示:
@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);
}
如您所见,CustomUserDetails 没有 newPassword
字段。
将此字段添加到此对象是否有意义?还有什么其他选择?这种情况下的最佳做法是什么?
最佳答案
首先,在 CustomUserDetails
类中添加 newPassword
字段是没有意义的。
其次,最好只更新不同端点中的密码(例如通过 POST
方法的 /change_password
、/update_password
等端点)。但是您可以使用 /signup
端点的 PUT
方法来更新 CustomUserDetails
字段,但在这种情况下忽略 password
字段。最好不要直截了当。
三、最佳实践
- 仅用于更新密码的单独端点
- 所有登录用户都允许使用此端点方法。
- 您应该采用两个值,一个是
oldPassword
,另一个是newPassword
- 在更新登录用户的密码之前,对旧密码和新密码进行哈希处理(哈希算法必须与您创建用户时相同)。
- 散列后,如果
oldPassword
与数据库中现有的散列密码匹配,则使用散列newPassword
更新字段
关于java - 向 CustomUsersCredentials 添加新密码,是好主意还是坏主意?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43969204/