MutableAcl.createAcl() 与自定义 UserDetailsService
MutableAcl.createAcl() with custom UserDetailsService
我目前正在尝试将 Spring 的 ACL 实施到我现有的应用程序中。
可悲的是,我被困在一个特定的点上,这似乎是由我的 UserDetailsService 引起的。
当我调用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 用户名。
我目前正在尝试将 Spring 的 ACL 实施到我现有的应用程序中。 可悲的是,我被困在一个特定的点上,这似乎是由我的 UserDetailsService 引起的。
当我调用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 用户名。