api-platform / api-platform/core

[Security] Support voter reasons in the "access denied" responses

Open
#7,331 0 comments 7 reactions 0 assignees View on GitHub
Dominant language
PHP
Stars
2.6k
Forks
980
Avg merge
2d 5h
Merged PRs (30d)
48

Description

**Description**
Symfony (since 7.3) supports Voters setting a "reason" for an access decision: https://github.com/symfony/symfony/pull/59771
Please implement an option to output the reason(s) given by the Voter(s) when access to an endpoint is denied.

**Example**
ApiResource on the User entity with security property:
```
new Delete(
security: "is_granted('DELETE', object)",
),
```

UserVoter:
```
case self::DELETE:
if (null !== $subject->getAccount()) {
$vote?->addReason('User has an associated account and cannot be deleted');
return false;
}
```

Possible problem response:
```
{
detail: "User has an associated account and cannot be deleted",
status: 403,
title: "An error occurred",
type: "/errors/403",
}
```

Or instead of modifying the `detail`, return a separate field that may contain a list of reasons, not just the last reason.

**Details**
APIP currently cannot output this reason when it throws an AccessDenied[Http]Exception in the AccessCheckerProvider because its ResourceAccessChecker uses the ExpressionLanguage, which currently has no support for specifying an AccessDecision object like `Symfony\Component\Security\Core\Authorization\AuthorizationChecker::isGranted` has, that could later be evaluated for the reasons.

APIP's ResourceAccessChecker has its own $authorizationChecker, which could be accessed after evaluating the expression. This $authorizationChecker has an $accessDecisionStack, which is sadly empty and private.
But it also has a (private) $accessDecisionManager, which again has an $accessDecisionStack. And this stack has the AccessDecision object with all votes and reasons, but I have no idea how APIP could access this. I hope someone has a better idea than overwriting all those classes/services with custom versions to allow access to those fields.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.