Доступ запрещен для просмотра и загрузки маршрутов в SonataMediaBundle и Symfony 4
Я использую Symfony 4 (точнее 4.1) с SonataAdminBundle и SonataMediaBundle.
Это мое 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
Если я бегу php bin/console debug:router
в выводе есть следующие маршруты:
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}
Первые два маршрута работают нормально, но когда я пробую другие два маршрута, например:
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
тогда я всегда получаю AccessDeniedException, хотя я аутентифицировался как ROLE_SUPER_ADMIN
,
Ошибка происходит в vendor/sonata-project/media-bundle/src/Controller/MediaController.php
в downloadAction
И в viewAction
, Я копался в исходном коде, но не могу найти причину исключения.
1 ответ
После некоторых исследований я нашел виновника и решил проблему. Здесь я хотел бы поделиться своими знаниями.
Как я уже упоминал в вопросе, исключения были выброшены из:
vendor/sonata-project/media-bundle/src/Controller/MediaController.php
в методах downloadAction
а также viewAction
, Это было следующее условие if:
if (!$this->get('sonata.media.pool')->getDownloadSecurity($media)->isGranted($media, $this->getCurrentRequest())) {
throw new AccessDeniedException();
}
который присутствует в обоих методах. Это привело меня к vendor/sonata-project/media-bundle/src/Provider/Pool.php
и далее vendor/sonata-project/media-bundle/src/Security/RolesDownloadStrategy.php
, Я не смог найти там ни одной ошибки или проблемы, но это открыло мне глаза на другую позицию в моей собственной конфигурации:
access_control:
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
Как я мог быть таким глупым? Путь /media
не заявлено в security.yml
и могут быть доступны не аутентифицированным пользователям. SonataMediaBundle
требуется по умолчанию ROLE_ADMIN
или же ROLE_SUPER_ADMIN
для загрузки / просмотра медиа.
Маршруты для Gallery
были доступны, потому что vendor/sonata-project/media-bundle/src/Controller/GalleryController.php
не проверяет, предоставляется ли доступ.
После нахождения виновника вопрос заключался в том, какой подход выбрать для решения проблемы.
1) Измените префикс маршрута:
sonata_media:
resource: '@SonataMediaBundle/Resources/config/routing/media.xml'
prefix: /admin/media
Объявленный путь в security.yml
охватывает теперь media
а также ROLE_ADMIN
а также ROLE_SUPER_ADMIN
может получить доступ к маршрутам.
Недостаток: что делать, если вы хотите выставить медиа вне администратора? А что если другие роли должны иметь к ним доступ?
2) Объявить новый путь в security.yml
:
access_control:
- { path: ^/media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
Теперь мы можем выставлять СМИ за пределами админа. Но другая проблема все еще остается: что, если нужны другие роли для доступа к СМИ?
3) Настройте другую стратегию загрузки в конфигурации для SonataMedia:
sonata_media:
# ...
contexts:
default: # the default context is mandatory
download:
strategy: sonata.media.security.connected_strategy
mode: http
# ...
и скорректировать путь:
access_control:
# ...
- { path: ^/media/, role: [IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED] }
# ...
Теперь каждый зарегистрированный пользователь может получить доступ к медиа. Это решение сработало для меня.
Однако это не универсальный рецепт. Пожалуйста, проверьте безопасность главы из официальной документации, чтобы получить более подробную информацию.