Spring Data Rest中的存储库访问控制基于用户原理

fra*_*cis 11 java spring spring-security spring-data spring-data-rest

我正在尝试实现细粒度访问控制,同时仍然利用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();

}
Run Code Online (Sandbox Code Playgroud)

虽然这有点单调乏味,但它似乎完成了我所追求的目标.(如果有人知道更好的方式,请随时告诉我!)

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

    @Override
    long count();

    @Override
    void delete(Integer integer);

    @Override
    void delete(MyObject entity);

    @Override
    void deleteAll();

    @Override
    boolean exists(Integer integer);
Run Code Online (Sandbox Code Playgroud)

这些方法要么采用IntegerID参数,要么根本不采用.看来我必须首先选择具有输入ID的实体,然后执行auth检查.

存储库中是否可以进行此类授权?

谢谢

编辑:

感谢ksokol,这似乎现在正在运作.

我在@Configuration课堂上添加了一个新的bean

@Bean
public EvaluationContextExtension securityExtension() {
    return new SecurityEvaluationContextExtensionImpl();
}
Run Code Online (Sandbox Code Playgroud)

此bean扩展EvaluationContextExtensionSupport并覆盖getRootObject以返回SecurityExpressionRoot保存我的自定义主体的bean .

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

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

Kam*_*kol 18

Spring Security 4.0开始,您可以访问Spring Data JPA查询中的安全上下文.

SecurityEvaluationContextExtensionbean 添加到bean上下文中:

@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
    return new SecurityEvaluationContextExtension();
}
Run Code Online (Sandbox Code Playgroud)

现在您应该能够访问PrincipalSpring Data查询:

@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);
Run Code Online (Sandbox Code Playgroud)

警告.查询可能有错误.我没时间测试它.