8000 [Security][new system] Voter can not vote anymore on "anonymous" · Issue #37523 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[Security][new system] Voter can not vote anymore on "anonymous" #37523
Closed
@romaricdrigon

Description

@romaricdrigon

Symfony version(s) affected: 5.1

Description

With the new Security system (5.1+) enabled

We have some a specific use case in our app I couldn't find how to handle: Voter can not handle anymore authorization of anonymous/unconnected users.

Our use case in details:

  • some objects in our application can be seen by everybody (including anonymous Users) or only some specific Users
  • so those objects each have isGranted(?User $user) method
  • to handle that, a Voter is used, it will fetch token from Security and call object's isGranted with the User it eventually found, or null

if there is no connected User, we are getting a InsufficientAuthenticationException: "Full authentication is required to access this resource"
The exception is raised by Symfony\Component\Security\Core\Authorization\AuthorizationChecker:isGranted(). It throws exception when there is no token. In the legacy system, an AnonymousToken was present.

How to reproduce

  1. set security.enable_authenticator_manager: true
  2. implement a Voter which allows anonymous Users
  3. configure any controller action with corresponding security attribute
  4. try to access it while unlogged

Possible Solution

Right now, I couldn't think of any work around in userland, as it happens in the authorization layer, outside of the authentication Guard we can configure.

Twig is working around it with a try... catch- which is also creating an inconsistency, btw (#30609) - but it prevents Voters from being able to decide if an anonymous User can be granted or not (cf. line 55 of Symfony\Component\Security\Core\Authorization\AuthorizationChecker:isGranted() - if there is no token, even if no exception is sent, all authorization checks are bypassed).

I have the impression a bypass over authentication/authorization separation - maybe something like AuthenticationVoter? Of Voter::supportsAnonymous?
AuthorizationManager could then call these voters even if no token is present.

Edit: I found an ugly workaround, adding an AnonymousAuthenticator called on every request, to re-add an AnonymousToken through an AnoymousPassport(internal class). It feels a little bit hacky to do that user-side, but it allows to keep BC:
https://gist.github.com/romaricdrigon/63f1d83ba7c516e6c6205b384c18376f

Additional context

RFC related to the same topic: #30609

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0