firewall setup with secure and open actions in same controller

196 Views Asked by At

I have an API that I'm looking to switch to using symfony, the one big challenge I'm seeing so far is that the firewall is pretty strict, nearly every example has the assumption that I'll want to secure all of /api or all of /secure but I have a situation where a controller will be mixed.

For example, /user/create would be secured under an authentication token, but /user/webhook is a publicly available endpoint that doesn't require a token to access.

How would I make the firewall play well with this setup without resorting to changing a whole bunch of endpoints?

ideally symfony has an auth attribute I could tag to the actions that I wish to be secured so it's controlled like routing is.

I'm looking to use the latest version of symfony (which as of this post is 6.2)

Appreciate any sort of guidance on a solution.

2

There are 2 best solutions below

1
Alberto Fecchi On BEST ANSWER

You can specify your access_control rules using regex in security.yaml. Order is important, so you need to specify rules from the most specific (path) to the less specific:

# config/packages/security.yaml
security:

    # ...
    access_control:
        - { path: ^/user/create, roles: ROLE_ADMIN }
        - { path: ^/user, roles: PUBLIC_ACCESS }

In this case, the access /user/create the ROLE_ADMIN is required. Every other path starting with /user (like /user/webhook) will be public accessibly. You can add as many rules as you like (see https://symfony.com/doc/current/security.html#allowing-unsecured-access-i-e-anonymous-users).

To use another approach, useful if you want to manage security directly in your controllers, you can use specific methods and attributes: https://symfony.com/doc/current/security.html#securing-controllers-and-other-code

0
amacrobert On

Using access_control is a blunt but effective way to control access for large portions of your site.

If you need something more fine-grained, you can declare required permissions per controller or per controller class.

For example:

use Symfony\Component\Security\Http\Attribute\IsGranted;

class PostController extends Controller
{
    #[IsGranted('ROLE_USER')]
    public function index()
    {
        // ...
    }
}

See Using Expressions in Security Access Controls for more information.