Spring Security/Spring Data Repository - 如何保护所有方法,具体取决于主体是否与 user_id 列匹配?

问题描述

我有多个 Spring Data Repositories,我的很多表都有 user_id 列。

我必须保护我的 API,以便每个用户只能查看和更改属于他的数据记录。 admin-role 用户除外,允许更改所有数据记录。

我的第一个意图是为每个存储库创建一个自定义实现并覆盖 save、delete、findAll 等方法。在自定义实现中,我可以获得主体并对用户组和 user_id 进行手动检查。

但这会导致很多自定义实现,万一我忘记覆盖一个方法(例如 findAll,这会很可怕),这可能会造成很大的安全问题。

有没有更好的方法来实现这一目标?我认为这应该是一个常见的安全案例,感觉我还没有找到最好的解决方案。

例如我有这个数据库表:

CREATE TABLE sell_order(
     id bigint PRIMARY KEY,user_id varchar(255),FOREIGN KEY (user_id) REFERENCES user_data (user_id)
);

还有这个 Spring Data Repository:

@RepositoryRestResource(collectionResourceRel = "sellorders",path = "sellorders")
public interface SellOrderRepository extends CrudRepository<SellOrder,Long> {

    @RestResource(path = "findByUserId",rel = "findByUserId")
    @Query(value = "SELECT s FROM SellOrder s WHERE s.userId = :userId")
    SellOrder findByUserId(@Param("userId") String userId);
}

解决方法

我必须在我的项目中实现相同的功能,我创建了以下身份验证方法:

     private boolean isSameAuthor(long uid) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        System.out.println((UserPrincipal)authentication.getPrincipal());
        UserPrincipal author =  (UserPrincipal)authentication.getPrincipal();
        return author.getUid() == uid;
    }

    private boolean isAdmin() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication.getAuthorities().stream().map(role -> role.getAuthority()).collect(Collectors.toSet()).contains("ROLE_ADMIN");
    }

在您的情况下,您应该通过 user_id。你可以使用这样的东西。