{"record":{"id":"040a492dbde6dc36","repo":"spring-projects/spring-security","slug":"denying-user-s-permission-s-on-object-with-id","errorCode":null,"errorMessage":"Denying user %s permission '%s' on object with Id %s","messagePattern":"Denying user (.+?) permission '(.+?)' on object with Id (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/springframework/security/access/expression/DenyAllPermissionEvaluator.java","lineNumber":58,"sourceCode":"\t/**\n\t * Always denies permission.\n\t * @return false always\n\t */\n\t@Override\n\tpublic boolean hasPermission(Authentication authentication, @Nullable Object target, Object permission) {\n\t\tthis.logger.warn(LogMessage.format(\"Denying user %s permission '%s' on object %s\", authentication.getName(),\n\t\t\t\tpermission, target));\n\t\treturn false;\n\t}\n\n\t/**\n\t * Always denies permission.\n\t * @return false always\n\t */\n\t@Override\n\tpublic boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,\n\t\t\tObject permission) {\n\t\tthis.logger.warn(LogMessage.format(\"Denying user %s permission '%s' on object with Id %s\",\n\t\t\t\tauthentication.getName(), permission, targetId));\n\t\treturn false;\n\t}\n\n}\n","sourceCodeStart":40,"sourceCodeEnd":64,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/core/src/main/java/org/springframework/security/access/expression/DenyAllPermissionEvaluator.java#L40-L64","documentation":"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.","triggerScenarios":"A SpEL expression such as hasPermission(#id, 'com.example.Document', 'READ') is evaluated while DenyAllPermissionEvaluator is the active evaluator.","commonSituations":"Using id+type style hasPermission expressions without a custom PermissionEvaluator; accidentally relying on Spring Security's default deny-all evaluator in production.","solutions":["Register a custom PermissionEvaluator implementing hasPermission(Serializable targetId, String targetType, Object permission)","Wire it into DefaultMethodSecurityExpressionHandler so it replaces the deny-all default","Or rewrite expressions to not use hasPermission if a simpler authority check suffices"],"exampleFix":"// before: default evaluator denies\n@PreAuthorize(\"hasPermission(#id, 'Document', 'READ')\")\n// after\nexpressionHandler.setPermissionEvaluator(new IdBasedPermissionEvaluator());","handlingStrategy":"validation","validationCode":"// Same guard for the id/targetType overload\nif (expressionHandler.getPermissionEvaluator() instanceof DenyAllPermissionEvaluator) {\n  throw new IllegalStateException(\"hasPermission(id,type,perm) will always deny; register an evaluator\");\n}","typeGuard":"boolean supportsIdChecks(PermissionEvaluator pe) {\n  return !(pe instanceof DenyAllPermissionEvaluator);\n}","tryCatchPattern":null,"preventionTips":["Implement both hasPermission overloads in custom evaluators","Test id+targetType permission expressions explicitly","Document which expression style your evaluator supports to avoid silent deny-all"],"tags":["spring-security","method-security","permission-evaluator","access-denied"],"backgroundTag":"permission-denied","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}