暂时想出了以下解决方案。由于我的项目相当简单,因此这可能无法用于更复杂的项目。
- 用户可以读取全部或没有某一类
的任何因此查询方法可以用含有hasRole
@PreAuthorize
进行注释的实体。
这个例外是我项目中的Container
实体。它可以包含Compound
的任何子类,并且用户可能没有权限查看它们全部。他们必须是过滤器。
为此,我创建了User
和Role
实体。 Compound
与Role
有一对一关系,该角色是Compound
的“read_role”。 User
和Role
有一个ManyToMany关系。
@Entity
public abstract class Compound {
//...
@OneToOne
private Role readRole;
//...
}
我所有的仓库实现QueryDSLPredicateExecutor
这里变得很有一手。我们不是在存储库中创建自定义的findBy方法,而是仅在服务层创建它们,并使用repositry.findAll(predicate)
和repository.findOne(predicate)
。谓词包含实际的用户输入+“安全过滤器”。
@PreAuthorize("hasRole('read_Container'")
public T getById(Long id) {
Predicate predicate = QCompoundContainer.compoundContainer.id.eq(id);
predicate = addSecurityFilter(predicate);
T container = getRepository().findOne(predicate);
return container;
}
private Predicate addSecurityFilter(Predicate predicate){
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
predicate = QCompoundContainer.compoundContainer.compound.readRole
.users.any().username.eq(userName).and(predicate);
return predicate;
}
注意:QCompoundContainer
是由QueryDSL生成的“元模型”类。
最后,你可能需要将QueryDSL路径初始化从Container
到User
:
@Entity
public abstract class CompoundContainer<T extends Compound>
//...
@QueryInit("readRole.users") // INITIALIZE QUERY PATH
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL,
targetEntity=Compound.class)
private T compound;
//...
}
忽略这最后一步可能导致NullPointerException
。
进一步提示:CompoundService
自动设置保存角色:
if (compound.getReadRole() == null) {
Role role = roleRepository.findByRoleName("read_" + getCompoundClassSimpleName());
if (role == null) {
role = new Role("read_" + getCompoundClassSimpleName());
role = roleRepository.save(role);
}
compound.setReadRole(role);
}
compound = getRepository().save(compound)
这工作。缺点是有点显而易见。同一个Role
与同一个Compound
类实现的每个实例相关联。
对于问题甲见[用户架构(http://static.springsource.org/spring-security/site/docs/3.2.x/reference/springsecurity-single.html#d0e8380])部分 – 2013-02-27 11:33:46
我的意思所以我可以调整查询以考虑当前用户的角色,例如。从给定的实体到角色和从角色到用户必须有一种关系。 – 2013-02-27 13:56:03
然后查看ACL http://static.springsource.org/spring-security/site/docs/3.2.x/reference/springsecurity-single.html#domain-acls和适当的数据库模式http:// static。 springsource.org/spring-security/site/docs/3.2.x/reference/springsecurity-single.html#dbschema-acl – 2013-02-27 14:07:48