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.
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:
in the methods
downloadActionandviewAction. It was the following if-condition:which is present in both methods. This led me to
vendor/sonata-project/media-bundle/src/Provider/Pool.php, and further tovendor/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:How could I be so stupid? The path
/mediais not declared insecurity.ymland can be accessed by not authenticated users. TheSonataMediaBundlerequires per defaultROLE_ADMINorROLE_SUPER_ADMINfor downloading/viewing the media.The routes for the
Gallerywere accessible becausevendor/sonata-project/media-bundle/src/Controller/GalleryController.phpdoesn'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:
The declared path in
security.ymlcovers now themediaandROLE_ADMINandROLE_SUPER_ADMINcan 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: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:
and adjust the path:
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.