如何限制某些用户使用 PUT 和 Spring Data Rest 编辑对象的所有属性?
How to restrict certain users from editing all attributes of an object using PUT with Spring Data Rest?
当使用 Spring Data Rest 时,有没有办法让某些用户使用 PUT 请求只编辑实体的一部分?
以此项为例:
{
"name": "Item1",
"description": "Description",
"creator": "User1"
}
让项目的创建者使用 PUT 请求编辑整个项目同时限制其他用户只能编辑 "description" 字段的最佳方法是什么?
我试过使用自定义验证器和事件处理程序,但没有成功。
我认为自定义 Validator 是您的正确选择。
首先 - 更新您的实体以使其保存之前的状态(感谢 @AlanHay):
@Entity
class ItemEntity {
@Transient
private ItemEntity previousState;
@PostLoad
private void setPreviousState(){
previousState = new ItemEntity();
//copy the fields
}
public ItemEntity getPreviousState(){
return previousState;
}
}
然后实现验证器,在其中检查当前用户 'authority' 是否更改了字段:
public class ItemValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
//...
}
@Override
public void validate(Object target, Errors errors) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
SimpleGrantedAuthority userRole = new SimpleGrantedAuthority("ROLE_USER");
if (authorities.contains(userRole)) {
ItemEntity item = (ItemEntity) target;
prevItem = item.getPreviousState();
String prevName = prevItem.getName();
String prevCreator = prevItem.getCreator();
String newName = item.getName();
String newCreator = item.getCreator();
if (!prevName.equals(newName)) {
errors.rejectValue("name", "You cannot change Name field!");
}
if (!prevCreator.equals(newCreator)) {
errors.rejectValue("creator", "You cannot change Creator field!");
}
}
// Other checks...
}
}
然后在 RepositoryRestConfigurerAdapter
中插入这个验证器:
@Configuration
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
v.addValidator("beforeCreate", itemValidator()); // POST (if needed)
v.addValidator("beforeSave", itemValidator()); // PUT/PATCH
super.configureValidatingRepositoryEventListener(v);
}
@Bean
ListingValidator itemValidator() {
return new ItemValidator();
}
}
我认为这应该可行...
当使用 Spring Data Rest 时,有没有办法让某些用户使用 PUT 请求只编辑实体的一部分?
以此项为例:
{
"name": "Item1",
"description": "Description",
"creator": "User1"
}
让项目的创建者使用 PUT 请求编辑整个项目同时限制其他用户只能编辑 "description" 字段的最佳方法是什么?
我试过使用自定义验证器和事件处理程序,但没有成功。
我认为自定义 Validator 是您的正确选择。
首先 - 更新您的实体以使其保存之前的状态(感谢 @AlanHay):
@Entity
class ItemEntity {
@Transient
private ItemEntity previousState;
@PostLoad
private void setPreviousState(){
previousState = new ItemEntity();
//copy the fields
}
public ItemEntity getPreviousState(){
return previousState;
}
}
然后实现验证器,在其中检查当前用户 'authority' 是否更改了字段:
public class ItemValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
//...
}
@Override
public void validate(Object target, Errors errors) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
SimpleGrantedAuthority userRole = new SimpleGrantedAuthority("ROLE_USER");
if (authorities.contains(userRole)) {
ItemEntity item = (ItemEntity) target;
prevItem = item.getPreviousState();
String prevName = prevItem.getName();
String prevCreator = prevItem.getCreator();
String newName = item.getName();
String newCreator = item.getCreator();
if (!prevName.equals(newName)) {
errors.rejectValue("name", "You cannot change Name field!");
}
if (!prevCreator.equals(newCreator)) {
errors.rejectValue("creator", "You cannot change Creator field!");
}
}
// Other checks...
}
}
然后在 RepositoryRestConfigurerAdapter
中插入这个验证器:
@Configuration
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
v.addValidator("beforeCreate", itemValidator()); // POST (if needed)
v.addValidator("beforeSave", itemValidator()); // PUT/PATCH
super.configureValidatingRepositoryEventListener(v);
}
@Bean
ListingValidator itemValidator() {
return new ItemValidator();
}
}
我认为这应该可行...