I am currently trying to implement Spring's ACLs into my existing application. Sadly i am stuck at a specific point which seems to be caused by my UserDetailsService.
The problem/error is the following when i call the createAcl()
function of the
MutableAcl
class like this:
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);
}
Inside of this function a new ObjectIdentity
is created, if this class instance does not yet have one. A new PrincipalSid
is created from the current Authentication
object for this purpose (saved inside the ACL_SID table). Like this:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
PrincipalSid sid = new PrincipalSid(auth);
this.createObjectIdentity(objectIdentity, sid);
The problem occurs when it tries to save the entry into the ACL_SID
table which is defined as this:
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)
);
As you can see the sid
is a VARCHAR with 100 characters. My custom User class contains a few properties which are mostly converted to a String representation, which causes the PrincipalSid
to be longer than 100 characters. Now the first obvious solution would be to just change the toString
method to only return the most essential values.
Still this seems kinda "hacky" to me. Is there a better solution?
The sid
column in ACL_SID
table should only contain the username, not the entire user object with its properties. To create a correct instance of PrincipalSid
, make sure at least one of following is true:
auth.getPrincipal()
returns an instance of UserDetails interface.
auth.getPrincipal().toString()
returns the username.