spring-projects/spring-security · error · AccessDeniedException
Authenticated principal required to operate with ACLs
Error message
Authenticated principal required to operate with ACLs
What it means
AclAuthorizationStrategyImpl.securityCheck() guards ACL modification operations (change ownership, auditing, general modifications). It throws AccessDeniedException when there is no authenticated principal in the SecurityContext at all — the operation cannot even be attributed to a user.
Source
Thrown at acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java:97
"One or three GrantedAuthority instances required");
if (auths.length == 3) {
this.gaTakeOwnership = auths[0];
this.gaModifyAuditing = auths[1];
this.gaGeneralChanges = auths[2];
}
else {
this.gaTakeOwnership = auths[0];
this.gaModifyAuditing = auths[0];
this.gaGeneralChanges = auths[0];
}
}
@Override
public void securityCheck(Acl acl, int changeType) {
SecurityContext context = this.securityContextHolderStrategy.getContext();
if ((context == null) || (context.getAuthentication() == null)
|| !context.getAuthentication().isAuthenticated()) {
throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
}
Authentication authentication = context.getAuthentication();
// Check if authorized by virtue of ACL ownership
Sid currentUser = createCurrentUser(authentication);
Sid owner = acl.getOwner();
if (owner != null && currentUser.equals(owner)
&& ((changeType == CHANGE_GENERAL) || (changeType == CHANGE_OWNERSHIP))) {
return;
}
// Iterate this principal's authorities to determine right
Collection<? extends GrantedAuthority> reachableGrantedAuthorities = this.roleHierarchy
.getReachableGrantedAuthorities(authentication.getAuthorities());
Set<String> authorities = AuthorityUtils.authorityListToSet(reachableGrantedAuthorities);
if (owner instanceof GrantedAuthoritySid
&& authorities.contains(((GrantedAuthoritySid) owner).getGrantedAuthority())) {
return;
}View on GitHub (pinned to 96852e8860)
Solutions
- Ensure a fully authenticated Authentication is set in the SecurityContext before ACL mutation calls
- In background jobs, set a system/principal authentication explicitly: SecurityContextHolder.getContext().setAuthentication(auth)
- Propagate SecurityContext to async threads via DelegatingSecurityContextAsyncTaskExecutor
- Verify anonymous authentication is not leaking into ACL administration code paths
Example fix
// before
// background thread: no security context
mutableAclService.createAcl(objectIdentity);
// after
Authentication auth = new UsernamePasswordAuthenticationToken(
"systemUser", "n/a", List.of(new SimpleGrantedAuthority("ROLE_ADMIN")));
SecurityContextHolder.getContext().setAuthentication(auth);
mutableAclService.createAcl(objectIdentity); Defensive patterns
Strategy: validation
Validate before calling
Authentication a = SecurityContextHolder.getContext().getAuthentication();
if (a == null || !a.isAuthenticated() || a instanceof AnonymousAuthenticationToken) {
throw new AccessDeniedException("ACL mutation requires an authenticated principal");
} Type guard
null
Try / catch
try {
mutableAclService.updateAcl(acl);
} catch (AccessDeniedException e) {
log.error("No authenticated principal for ACL operation");
throw e;
} Prevention
- Never call ACL write APIs from unauthenticated threads without establishing an Authentication
- Use DelegatingSecurityContext* executors for async ACL work
- Assert a populated SecurityContext in integration tests for ACL paths
When it happens
Trigger: Calling mutableAclService.createAcl/updateAcl/deleteAcl (or acl.setOwner/setEntriesInheriting etc.) while SecurityContextHolder holds null context, null Authentication, or an Authentication with isAuthenticated()==false (e.g. AnonymousAuthenticationToken).
Common situations: Performing ACL writes in background threads/async tasks/schedulers where no SecurityContext exists; calling ACL APIs before authentication is established; forgetting to propagate SecurityContext to @Async/executors.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- AclEntryAfterInvocationProvider.noPermission
- Principal does not have required ACL permissions to perform
- Can't change password as no Authentication object found in c
- Can't change password as no Authentication object found in c
- An Authentication object was not found in the SecurityContex
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/afcf640d4bab1ca5.
Report an issue: GitHub.