Spring security 如何获取用户可以使用ACL相关表访问的对象列表

Spring security 如何获取用户可以使用ACL相关表访问的对象列表,spring-security,acl,spring-security-acl,Spring Security,Acl,Spring Security Acl,我正在设计一个对用户管理/权限有很多要求的系统,因此我决定使用Spring Security ACL在域对象级别管理权限 尽管如此,使用ACL来维护用户和实体之间的关系迫使我们依赖ACL在UI上显示数据 Spring Security提供的PostFilter解决方案很好地过滤了用户可以/看不到的对象,但在处理具有数百/数千个条目的实体时,它存在一个很大的性能问题,因为我们需要从数据库加载所有内容,然后丢弃用户不允许的对象“看” 这里描述了这个问题——但是在该功能可用之前需要一些时间。因此,我试

我正在设计一个对用户管理/权限有很多要求的系统,因此我决定使用Spring Security ACL在域对象级别管理权限

尽管如此,使用ACL来维护用户和实体之间的关系迫使我们依赖ACL在UI上显示数据

Spring Security提供的PostFilter解决方案很好地过滤了用户可以/看不到的对象,但在处理具有数百/数千个条目的实体时,它存在一个很大的性能问题,因为我们需要从数据库加载所有内容,然后丢弃用户不允许的对象“看”

这里描述了这个问题——但是在该功能可用之前需要一些时间。因此,我试图找到一种解决方法来使用Spring安全ACL,但避免性能问题

我考虑实现一些代码来检索用户可以访问的对象(在身份验证过程之后),并保持这些信息可用于每个请求,以允许开发人员使用这些信息执行查询,而不依赖PostFilter

为了实现这一点,我试图找到一种方法来检索给定主体/授权的权限列表,但我无法找到一种方法来使用可用的AclService实现来实现这一点

示例
aclService.getObjectIdentityList(,)

注意:该方法应使用继承结构,并包括从父项继承的所有ObjectIdentity

有没有关于获取数据的建议或解决此问题的其他方法


更新

我已经找到了一种方法来检索用户可以访问的对象列表

List<ObjectIdentity> childObjects = aclService.findChildren(objectIdentity);
Map<ObjectIdentity, Acl> result = aclService.readAclsById(childObjects, sids);
List childObjects=aclService.findChildren(objectIdentity);
映射结果=aclService.readAclsById(子对象,SID);
这种方法对我们很有效,因为我们只有几个实体,它们的访问由ACL控制,所以我们可以构建用户可以访问的ObjectSideEntity列表

虽然,正在返回的映射正在返回正在传递的ObjectIdentity的所有ACL,但是我需要检查用户是否有权访问正在返回的每个ObjectIdentity


您是否有一种简单的方法来完成此操作或简化所有逻辑?

当前处理较大数据集的方法是更新查询以将当前登录的用户包括在查询中。例如,您可以使用Spring Security和Spring data integration来更新查询以引用当前用户:

@Query("select d from MyDomain d where d.owner = #{principal.name}")

显然,这并不理想,因为您需要手动管理权限。一旦我们解决了问题,Spring可以自动为您完成许多繁重的工作。

我遇到了这个问题,因为我需要一个解决方案来解决权限不足的问题。查看jdbaclservice.findChildren()让我找到这个问题

private final String FIND_OBJECTS_WITH_ACCESS = ""+
          "SELECT " +
          "    obj.object_id_identity AS obj_id, " +
          "    class.class AS class " +
          "FROM " +
          "    acl_object_identity obj, " +
          "    acl_class class, " +
          "    acl_entry entry " +
          "WHERE " +
          "    obj.object_id_class = class.id " +
          "    and entry.granting = true " +
          "    and entry.acl_object_identity = obj.id " +
          "    and entry.sid = (SELECT id FROM acl_sid WHERE sid = ?) " +
          "    and obj.object_id_class = (SELECT id FROM acl_class WHERE acl_class.class = ?) " +
          "GROUP BY " +
          "    obj.object_id_identity, " +
          "    class.class ";


public List<ObjectIdentity> getObjectsWithAccess(Class clazz, String sid) {
    Object[] args = { sid, clazz.getName() };
    List<ObjectIdentity> objects = _jdbcTemplate.query(FIND_OBJECTS_WITH_ACCESS, args, getRowMapper());
    return objects.size() == 0 ? null : objects;
}

private RowMapper<ObjectIdentity> getRowMapper() {
    return (rs, rowNum) -> {
        String javaType = rs.getString("class");
        Long identifier = rs.getLong("obj_id");
        return new ObjectIdentityImpl(javaType, identifier);
    };
}
private final String FIND_OBJECTS_WITH_ACCESS=“”+
“选择”+
“obj.object\u id\u标识为obj\u id,”+
“类。类作为类”+
“来自”+
“acl\u对象\u标识对象”+
“acl_类”+
“acl_条目”+
“哪里”+
“obj.object\u id\u class=class.id”+
“and entry.grating=true”+
“和entry.acl\u object\u identity=obj.id”+
“和entry.sid=(从acl_sid中选择id,其中sid=?)”+
“和obj.object\u id\u class=(从acl\u类中选择id,其中acl\u class.class=?)”+
“分组依据”+
“obj.object\u id\u标识”+
“阶级,阶级”;
公共列表GetObjectSwitAccess(类clazz,字符串sid){
对象[]args={sid,clazz.getName()};
List objects=_jdbcTemplate.query(使用_访问、args、getRowMapper()查找_objects);
返回objects.size()==0?null:对象;
}
私有行映射器getRowMapper(){
返回(rs,rowNum)->{
String javaType=rs.getString(“类”);
长标识符=rs.getLong(“obj_id”);
返回新的ObjectIdentityImpl(javaType,标识符);
};
}

谢谢你的回答@rob winch,但这种方法迫使我在域中保持这种关系,并失去Spring Security ACL应该提供的关注点的分离,对吗?另外,如果你想使用ACL的继承,你会如何处理?你是对的,这并不理想。这就是为什么我们有上述JIRA。不幸的是当然,在那之前,这是我们拥有的最好的解决方案。如果您希望包括具有非所有者访问权限的用户,则这不起作用。效果很好,尽管我已使用JOIN子句重写了此查询