2

I use Symfony 4 (more precise 4.1) with SonataAdminBundle and SonataMediaBundle.

This is my config/routes/sonata_media.yaml:

sonata_media_gallery:
    resource: '@SonataMediaBundle/Resources/config/routing/gallery.xml'
    prefix: /media/gallery

sonata_media:
    resource: '@SonataMediaBundle/Resources/config/routing/media.xml'
    prefix: /media

If I run php bin/console debug:router there are the following routes in the output:

sonata_media_gallery_index    ANY    ANY    ANY    /media/gallery/
sonata_media_gallery_view     ANY    ANY    ANY    /media/gallery/view/{id}
sonata_media_view             ANY    ANY    ANY    /media/view/{id}/{format}
sonata_media_download         ANY    ANY    ANY    /media/download/{id}/{format}

The first two routes work fine, but when I try the other two routes, for example:

http://localhost:8000/media/view/
http://localhost:8000/media/view/1/default
http://localhost:8000/media/download/1
http://localhost:8000/media/download/1/default

then I always get AccessDeniedException, even though I'm authenticated as ROLE_SUPER_ADMIN.

The error happens in vendor/sonata-project/media-bundle/src/Controller/MediaController.php in downloadAction and in viewAction. I was digging around in the source code, but can't find the reason for the exception thrown.

cezar
  • 11,616
  • 6
  • 48
  • 84

1 Answers1

2

After some research I found the culprit and solved the problem. Here I'd like to share my knowledge.

As I mentioned in the question, the exceptions were thrown from:

vendor/sonata-project/media-bundle/src/Controller/MediaController.php

in the methods downloadAction and viewAction. It was the following if-condition:

if (!$this->get('sonata.media.pool')->getDownloadSecurity($media)->isGranted($media, $this->getCurrentRequest())) {
    throw new AccessDeniedException();
}

which is present in both methods. This led me to vendor/sonata-project/media-bundle/src/Provider/Pool.php, and further to vendor/sonata-project/media-bundle/src/Security/RolesDownloadStrategy.php. I couldn't find any bug or problem there, but it opened my eyes to another position in my own configuration:

access_control:
    - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
    - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

How could I be so stupid? The path /media is not declared in security.yml and can be accessed by not authenticated users. The SonataMediaBundle requires per default ROLE_ADMIN or ROLE_SUPER_ADMIN for downloading/viewing the media.

The routes for the Gallery were accessible because vendor/sonata-project/media-bundle/src/Controller/GalleryController.php doesn't check if access is granted.

After finding the culprit the question was which approach to chose to solve the problem

1) Change the route prefix:

sonata_media:
    resource: '@SonataMediaBundle/Resources/config/routing/media.xml'
    prefix: /admin/media

The declared path in security.yml covers now the media and ROLE_ADMIN and ROLE_SUPER_ADMIN can access the routes.

Disadvantage: what if you want to expose the media outside of the admin? And what if other roles should be able to access them.

2) Declare a new path in security.yml:

access_control:
    - { path: ^/media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }

Now we can expose the media outside of the admin. But the other issue is still there: what if other roles need to access the media?

3) Configure another download strategy in the config for SonataMedia:

sonata_media:
    # ...
    contexts:
        default:  # the default context is mandatory
            download:
                strategy: sonata.media.security.connected_strategy
                mode: http
    # ...

and adjust the path:

access_control:
    # ...
    - { path: ^/media/, role: [IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED] }
    # ...

Now every logged in user can access the media. This solution worked for me.

However it is not a one-size-fits-all recipe. Please check the chapter security from the official documentation to get more detailed information.

cezar
  • 11,616
  • 6
  • 48
  • 84
  • 1
    Omg thanks a lot. Had the same issue in my application and didn't find the error because of searching in the wrong files. – sensi Nov 16 '18 at 16:46