Symfony run argument value resolver after security resolved

961 Views Asked by At

I have a ArgumentValueResolverInterface that creates and validates DTOs.
I have also setup a firewall to protect routes and additionally use IsGranted attribute for fine grained access control.

Problem is that the value resolver and validation runs before the security firewall and show validation errors even if the request is unauthenticated.

How can I change the value resolver to run after security is resolved? Is this even possible?

class RequestDTOValueResolver implements ArgumentValueResolverInterface
{

    /**
     * RequestDTOValueResolver constructor.
     * @param ValidatorInterface $validator
     */
    public function __construct(protected ValidatorInterface $validator)
    {}


    /**
     * @inheritDoc
     */
    public function supports(Request $request, ArgumentMetadata $argument): bool
    {
        return is_subclass_of($argument->getType(), RequestDTOInterface::class);
    }

    /**
     * @inheritDoc
     * @throws ValidationException
     * @throws Exception
     */
    public function resolve(Request $request, ArgumentMetadata $argument): iterable
    {

        $className = $argument->getType();

        /** @var AbstractRequestDTO $dto */
        $dto = new $className($request); //$this->parseRequest($request, $argument);
        $groups = $dto->getGroups();

        $errors = $this->validator->validate($dto, null, !empty($groups) ? $groups : null);

        if ($errors->count()) {
            throw ValidationException::create($errors, "One or more fields are invalid.");
        }

        yield $dto;
    }


}
1

There are 1 best solutions below

0
Axel On

According to the official documentation, which is available here (it's not so different across different SF versions) : https://symfony.com/doc/5.2/controller/argument_value_resolver.html

You could probably achieve your goal by setting the proper priority

 App\ArgumentResolver\UserValueResolver:
    tags:
        - { name: controller.argument_value_resolver, priority: 50 }

I would also advice to check in which order each service is being run. Here you can see how it's done by SF:

https://symfony.com/doc/current/introduction/http_fundamentals.html