Доступ запрещен для просмотра и загрузки маршрутов в 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. Я копался в исходном коде, но не могу найти причину сгенерированного исключения.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
2
0
281
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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] }
    # ...

Теперь каждый авторизованный пользователь может получить доступ к медиа. Это решение сработало для меня.

Однако это не универсальный рецепт. Пожалуйста, проверьте главу безопасность в официальной документации, чтобы получить более подробную информацию.

Омг, спасибо большое. Была такая же проблема в моем приложении, и я не обнаружил ошибку из-за поиска в неправильных файлах.

sensi 16.11.2018 17:46

Другие вопросы по теме