MutableAcl.createAcl() 与自定义 UserDetailsS​​ervice

MutableAcl.createAcl() with custom UserDetailsService

我目前正在尝试将 Spring 的 ACL 实施到我现有的应用程序中。 可悲的是,我被困在一个特定的点上,这似乎是由我的 UserDetailsS​​ervice 引起的。

当我调用createAcl()函数时,problem/error如下 MutableAcl class 像这样:

public void addPermission(long objectId, Sid recipient, Permission permission, Class clazz) {
    MutableAcl acl;
    ObjectIdentity oid = new ObjectIdentityImpl(clazz.getCanonicalName(), objectId);

    try {
        acl = (MutableAcl) mutableAclService.readAclById(oid);
    } catch (NotFoundException nfe) {
        acl = mutableAclService.createAcl(oid);
    }

    acl.insertAce(acl.getEntries().size(), permission, recipient, true);
    mutableAclService.updateAcl(acl);
}

如果此 class 实例还没有,则在此函数内部创建一个新的 ObjectIdentity。为此,从当前 Authentication 对象创建了一个新的 PrincipalSid(保存在 ACL_SID table 中)。像这样:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
PrincipalSid sid = new PrincipalSid(auth);
this.createObjectIdentity(objectIdentity, sid);

当它试图将条目保存到定义为 ACL_SID table 时出现问题:

CREATE TABLE IF NOT EXISTS ACL_SID (
  id BIGSERIAL NOT NULL PRIMARY KEY,
  principal BOOLEAN NOT NULL,
  sid VARCHAR(100) NOT NULL,
  CONSTRAINT UNIQUE_UK_1 UNIQUE(sid,principal)
);

如您所见,sid 是一个包含 100 个字符的 VARCHAR。我的自定义用户 class 包含一些属性,这些属性大多转换为字符串表示形式,这导致 PrincipalSid 超过 100 个字符。现在第一个明显的解决方案是将 toString 方法更改为仅 return 最基本的值。 对我来说,这仍然有点 "hacky"。有更好的解决方案吗?

ACL_SID table 中的 sid 列应该只包含用户名,而不是整个用户对象及其属性。要创建 PrincipalSid 的正确实例,请确保至少满足以下一项:

  • auth.getPrincipal() returns UserDetails 接口的实例。

  • auth.getPrincipal().toString() returns 用户名。