spring-projects/spring-security · error · AccessDeniedException

AclEntryAfterInvocationProvider.noPermission

AclEntryAfterInvocationProvider.noPermission

Error message

Authentication {0} has NO permissions to the domain object {1}

What it means

AclEntryAfterInvocationProvider filters or authorizes a method's returned domain object against the ACL system. When the current Authentication holds none of the required permissions (configured via requirePermission entries) on the object's ACL, it throws AccessDeniedException with message code 'AclEntryAfterInvocationProvider.noPermission'.

Source

Thrown at acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java:111

		for (ConfigAttribute attr : config) {
			if (!this.supports(attr)) {
				continue;
			}

			// Need to make an access decision on this invocation
			if (hasPermission(authentication, returnedObject)) {
				return returnedObject;
			}

			logger.debug("Denying access");
			throw new AccessDeniedException(this.messages.getMessage("AclEntryAfterInvocationProvider.noPermission",
					new Object[] { authentication.getName(), returnedObject },
					"Authentication {0} has NO permissions to the domain object {1}"));
		}

		return returnedObject;

View on GitHub (pinned to 96852e8860)

Solutions

  1. Insert an ACE granting the principal (or its granted authority) the required permission: acl.insertAce(relevantOrder, BasePermission.READ, sid, true)
  2. Verify the AclService can resolve the ObjectIdentity of the returned object (mutableAclService.createObjectIdentity if missing)
  3. Check SidRetrievalStrategy returns the expected SIDs (user + authorities)
  4. Confirm requirePermission list matches the permissions actually granted

Example fix

// before
// object has no ACEs for current user
MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);

// after
MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);
acl.insertAce(acl.getEntries().size(), BasePermission.READ,
    new PrincipalSid(authentication), true);
mutableAclService.updateAcl(acl);
Defensive patterns

Strategy: try-catch

Validate before calling

Acl acl = aclService.readAclById(objectIdentity);
boolean allowed = acl.isGranted(List.of(BasePermission.READ),
    sidRetrievalStrategy.getSids(authentication), false);

Type guard

null

Try / catch

try {
    Object result = securedService.readDomainObject(id);
} catch (AccessDeniedException e) {
    throw new ResponseStatusException(HttpStatus.FORBIDDEN, "No ACL permission on object");
}

Prevention

When it happens

Trigger: afterInvocation runs on a returned domain object (or collection) and acl.isGranted() for the caller's SIDs against the configured requirePermission list (e.g. BasePermission.READ) returns false; also triggered if the ACL has no ACEs at all for the principal.

Common situations: Object exists but was never inserted into the ACL tables; SIDs not resolving to the caller's groups; ACL lookup using a different ObjectIdentity than the one with granted ACEs; forgetting to grant READ to the role owning the object.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/178f777ee2e1cd70. Report an issue: GitHub.