Spring Data Rest中的存储库访问控制基于用户原理 [英] Repository access control in Spring Data Rest based off user princpal
问题描述
我正在尝试实现细粒度访问控制,同时仍然利用Spring数据休息。
I'm attempting to implement fine grain access control while still taking advantage of Spring data rest.
我正在努力保护 CrudRepository
,以便用户只能修改或插入属于他们的数据。我正在使用 @PreAuthorize
/ @PostAuthorize
和 @PreFilter
/ @PostFilter
将访问权限锁定到当前主体。
I'm working on securing a CrudRepository
so users can only modify or insert data that belongs to them. I'm making use of @PreAuthorize
/@PostAuthorize
and @PreFilter
/@PostFilter
to lock access down to the current principal.
到目前为止,我的存储库看起来像这样。
So far my repository looks like this.
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();
}
虽然这有点乏味,但它似乎确实完成了我追求的是什么。 (如果有人知道更好的方法,请随时告诉我!)
While this is a bit tedious, it does seem to accomplish what I'm after. (If anyone knows a better way, feel free to let me know!)
我遇到问题的地方是 delete()
, count()
和 exists()
Where I'm running into problems is with delete()
, count()
and exists()
@Override
long count();
@Override
void delete(Integer integer);
@Override
void delete(MyObject entity);
@Override
void deleteAll();
@Override
boolean exists(Integer integer);
这些方法采用整数
ID参数或根本没有。看起来我必须首先选择具有输入ID的实体,然后执行身份验证检查。
These methods either take an Integer
ID parameter or none at all. It seems like I would have to first select the entity with the input ID and then perform the auth check.
存储库中是否可以进行此类授权?
Is this type of authorization possible within the repository?
谢谢
编辑:
感谢ksokol现在似乎正在运作。
Thanks to ksokol this seems to be working now.
我在 @Configuration
类中添加了一个新bean
I added a new bean to a @Configuration
class
@Bean
public EvaluationContextExtension securityExtension() {
return new SecurityEvaluationContextExtensionImpl();
}
此bean扩展 EvaluationContextExtensionSupport
并覆盖 getRootObject
以返回包含我的自定义主体的 SecurityExpressionRoot
。
This bean extends EvaluationContextExtensionSupport
and overrides getRootObject
to return a SecurityExpressionRoot
that holds my custom principal.
public class SecurityEvaluationContextExtensionImpl extends EvaluationContextExtensionSupport {
@Override
public String getExtensionId() {
return "security";
}
@Override
public Object getRootObject() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return new SecurityExpressionRoot(authentication){};
}
}
推荐答案
As Spring Security 4.0 ,您可以访问安全性Spring Data JPA查询中的上下文。
As of Spring Security 4.0 you can access security context in Spring Data JPA queries.
将 SecurityEvaluationContextExtension
bean添加到bean上下文中:
Add SecurityEvaluationContextExtension
bean to your bean context:
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
现在你应该可以访问 Principal 你的Spring数据查询中的code>:
@Query("select count(m) from MyObject as m where m.user.id = ?#{ principal?.id }")
@Override
long count();
@Modifying
@Query("delete from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
@Override
void delete(Integer integer);
@Modifying
@Query("delete from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
@Override
void delete(MyObject entity);
@Modifying
@Query("delete from MyObject as m where m.user.id = ?#{ principal?.id }")
@Override
void deleteAll();
@Query("select 1 from MyObject as m where m.id = ?1 and m.user.id = ?#{ principal?.id }")
@Override
boolean exists(Integer integer);
小心。查询可能有错误。我没时间测试它。
Caution. Queries might have errors. I hadn't the time to test it.
这篇关于Spring Data Rest中的存储库访问控制基于用户原理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!