Tôi đang cố gắng thực hiện kiểm soát truy cập hạt mịn trong khi vẫn tận dụng phần còn lại của dữ liệu Spring.Kiểm soát truy cập kho lưu trữ trong Spring Data Rest dựa trên người dùng nguyên tắc
Tôi đang làm việc để bảo mật CrudRepository
để người dùng chỉ có thể sửa đổi hoặc chèn dữ liệu thuộc về họ. Tôi đang sử dụng @PreAuthorize
/@PostAuthorize
và @PreFilter
/@PostFilter
để khóa quyền truy cập xuống hiệu trưởng hiện tại.
Kho lưu trữ của tôi trông như thế này.
public interface MyRepository extends CrudRepository<MyObject, Integer> {
@PreAuthorize("#entity.userId == principal.id")
@Override
<S extends MyObject> S save(S entity);
@PreFilter("filterObject.userId === principal.id")
@Override
<S extends MyObject> Iterable<S> save(Iterable<S> entities);
@PostAuthorize("returnObject.userId == principal.id")
@Override
MyObject findOne(Integer integer);
@PostFilter("filterObject.userId == principal.id")
@Override
Iterable<MyObject> findAll();
}
Trong khi điều này hơi tẻ nhạt, có vẻ như tôi đã đạt được những gì tôi theo đuổi. (Nếu có ai biết một cách tốt hơn, cảm thấy tự do để cho tôi biết!)
Nơi tôi đang chạy vào vấn đề là với delete()
, count()
và exists()
@Override
long count();
@Override
void delete(Integer integer);
@Override
void delete(MyObject entity);
@Override
void deleteAll();
@Override
boolean exists(Integer integer);
Những phương pháp này hoặc lấy một tham số Integer
ID hoặc không có gì cả. Có vẻ như tôi sẽ phải chọn thực thể đầu tiên với ID đầu vào và sau đó thực hiện kiểm tra auth.
Loại ủy quyền này có thể có trong kho lưu trữ không?
Cảm ơn
Edit:
Nhờ ksokol này dường như được làm việc ngay bây giờ.
tôi đã thêm một bean mới cho một lớp @Configuration
@Bean
public EvaluationContextExtension securityExtension() {
return new SecurityEvaluationContextExtensionImpl();
}
đậu này mở rộng EvaluationContextExtensionSupport
và ghi đè getRootObject
để trả về một SecurityExpressionRoot
chứa chủ yếu tùy chỉnh của tôi.
public class SecurityEvaluationContextExtensionImpl extends EvaluationContextExtensionSupport {
@Override
public String getExtensionId() {
return "security";
}
@Override
public Object getRootObject() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return new SecurityExpressionRoot(authentication){};
}
}
Cảm ơn ksokol, các truy vấn JPQL này sẽ ghi đè hành vi được thực thi mặc định trong thời gian chạy? Làm thế nào bạn tham khảo các tham số phương pháp, bạn đang sử dụng? 1 – francis
Có. Chúng ghi đè các truy vấn được tạo thời gian chạy. Bằng cách sử dụng '?1' vv bạn đang tham khảo các tham số phương thức bên trong các truy vấn của bạn. Xem [Sử dụng @Query] (http://docs.spring.io/spring-data/jpa/docs/1.8.0.RELEASE/reference/html/#jpa.query-methods.at-query) để biết thêm thông tin. –