bjhonna
bjhonna

Reputation: 21

Symfony - exclude specific route from security path

In my security.yaml file I have:

 access_control:
    - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

But I have defined one more route: api/doc and api/doc.json which I want to exclude from this specific group like:

- { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }

and I want to exclude just for this specific path but not from all api/ extensions.

Do I need to put this endpoint above first one or is there another way?

Upvotes: 1

Views: 2722

Answers (2)

Lorenzo Piersante
Lorenzo Piersante

Reputation: 158

Just had the same issue and william's proposed solution wasn't working for me aswell, solved it adding to security.yaml file the following lines of code:

security:
    firewalls:
        api_doc:
            pattern: ^/api/doc
            anonymous: true

My application use use symfony 5.4 and php 8.1

Upvotes: 0

Williams A.
Williams A.

Reputation: 743

You didn't specify the version of Symfony you are using but the same applies for most of versions.

In the documentation states the following:

For each incoming request, Symfony checks each access_control entry to find one that matches the current request. As soon as it finds a matching access_control entry, it stops - only the first matching access_control is used to enforce access.

So, this means that you should put first the paths that need the IS_AUTHENTICATED_ANONYMOUSLY role. This way, you only allow non authenticated sessions first an then check for your custom roles.

For example:

    access_control:
        - { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

And your controller definition should be more or less like this:

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class TestController
{
    /** @Route(name="api_doc", path="api/doc") */
    public function apiDoc()
    {
        return new Response('This is public');
    }
    
    /** @Route(name="api", path="api") */
    public function api()
    {
        return new Response('This is private');
    }
}

You can read more about it here.

Upvotes: 2

Related Questions