gpt4 book ai didi

java - Spring Data Rest 中基于用户主体的存储库访问控制

转载 作者:IT老高 更新时间:2023-10-28 13:45:47 29 4
gpt4 key购买 nike

我正在尝试实现细粒度访问控制,同时仍然利用 Spring 数据休息。

我正在努力保护 CrudRepository,以便用户只能修改或插入属于他们的数据。我正在使用 @PreAuthorize/@PostAuthorize@PreFilter/@PostFilter 来锁定访问权限现任校长。

到目前为止,我的存储库看起来像这样。

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();

}

虽然这有点乏味,但它似乎确实完成了我所追求的。 (如果有人知道更好的方法,请随时告诉我!)

我遇到问题的地方是 delete()count()exists()

    @Override
long count();

@Override
void delete(Integer integer);

@Override
void delete(MyObject entity);

@Override
void deleteAll();

@Override
boolean exists(Integer integer);

这些方法要么采用 Integer ID 参数,要么根本不采用。似乎我必须首先选择具有输入 ID 的实体,然后执行身份验证检查。

在存储库中是否可以进行这种类型的授权?

谢谢

编辑:

感谢 ksokol,这似乎现在可以工作了。

我向 @Configuration 类添加了一个新 bean

@Bean
public EvaluationContextExtension securityExtension() {
return new SecurityEvaluationContextExtensionImpl();
}

此 bean 扩展了 EvaluationContextExtensionSupport 并覆盖 getRootObject 以返回包含我的自定义主体的 SecurityExpressionRoot

public class SecurityEvaluationContextExtensionImpl extends EvaluationContextExtensionSupport {
@Override
public String getExtensionId() {
return "security";
}

@Override
public Object getRootObject() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return new SecurityExpressionRoot(authentication){};
}
}

最佳答案

截至 Spring Security 4.0您可以在 Spring Data JPA 查询中访问安全上下文。

SecurityEvaluationContextExtension bean 添加到您的 bean 上下文中:

@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}

现在您应该可以在 Spring Data 查询中访问 Principal:

@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);

小心。查询可能有错误。我没有时间测试它。

关于java - Spring Data Rest 中基于用户主体的存储库访问控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29688195/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com