防止通过 Spring 数据中的 POST 请求更新记录

Preventing updation of records through a POST request in Spring Data Rest

我在我的 Spring 启动应用程序中使用 spring-data-rest,我注意到 POST 请求中有一个奇怪的行为。

如果我向我的 http://<basepath>/<repository> 端点发出 POST 请求,并且我的正文包含 id 值,那么 Spring 会尝试使用该 ID 值更新记录。但如果该记录的版本字段不为零,那么这样的 POST 请求 returns 错误

Object of class [com.foo.bar.schema.entity] with identifier [c6aba26a-79a9-34e4-a520-b447e446c2bd]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.foo.bar.schema.entity#c6aba26a-79a9-34e4-a520-b447e446c2bd]

获得此错误的解决方案会很好,但我不希望有人通过 POST 请求通过传递记录的标识符来更新记录。我有 PUT/PATCH。

有什么方法可以做到这一点吗?

我找到了处理这个问题的方法。我在自动装配 HttpServletRequest 的地方使用自定义 PermissionEvaluator,然后在 hasPermission 方法中检查 request.getMethod() 是否为 POST 并且实体有没有身份证。

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
    private HttpServletRequest request;

    @Autowired
    public CustomPermissionEvaluator(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        if (targetDomainObject instanceof TableEntity) {
            TableEntity entity = (TableEntity) targetDomainObject;
            if (HttpMethod.resolve(request.getMethod()) == HttpMethod.POST && entity.getId() != null) {
                return false;
            }
        }
        return true;
    }
}