spring-projects/spring-security · warning

Denying user permission ' ' on object with Id

Error message

Denying user %s permission '%s' on object with Id %s

What it means

The second DenyAllPermissionEvaluator overload handles hasPermission(authentication, targetId, targetType, permission) and, like the object-based variant, always logs a denial and returns false. It guarantees fail-closed behavior for id/targetType-based permission checks when no real evaluator is configured.

Solutions

  1. Register a custom PermissionEvaluator implementing hasPermission(Serializable targetId, String targetType, Object permission)
  2. Wire it into DefaultMethodSecurityExpressionHandler so it replaces the deny-all default
  3. Or rewrite expressions to not use hasPermission if a simpler authority check suffices

Example fix

// before: default evaluator denies
@PreAuthorize("hasPermission(#id, 'Document', 'READ')")
// after
expressionHandler.setPermissionEvaluator(new IdBasedPermissionEvaluator());
Defensive patterns

Strategy: validation

Validate before calling

// Same guard for the id/targetType overload
if (expressionHandler.getPermissionEvaluator() instanceof DenyAllPermissionEvaluator) {
  throw new IllegalStateException("hasPermission(id,type,perm) will always deny; register an evaluator");
}

Type guard

boolean supportsIdChecks(PermissionEvaluator pe) {
  return !(pe instanceof DenyAllPermissionEvaluator);
}

Prevention

When it happens

Trigger: A SpEL expression such as hasPermission(#id, 'com.example.Document', 'READ') is evaluated while DenyAllPermissionEvaluator is the active evaluator.

Common situations: Using id+type style hasPermission expressions without a custom PermissionEvaluator; accidentally relying on Spring Security's default deny-all evaluator in production.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/springframework/security/access/expression/DenyAllPermissionEvaluator.java:58

	/**
	 * Always denies permission.
	 * @return false always
	 */
	@Override
	public boolean hasPermission(Authentication authentication, @Nullable Object target, Object permission) {
		this.logger.warn(LogMessage.format("Denying user %s permission '%s' on object %s", authentication.getName(),
				permission, target));
		return false;
	}

	/**
	 * Always denies permission.
	 * @return false always
	 */
	@Override
	public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
			Object permission) {
		this.logger.warn(LogMessage.format("Denying user %s permission '%s' on object with Id %s",
				authentication.getName(), permission, targetId));
		return false;
	}

}

View on GitHub (pinned to 96852e8860)