访问被拒绝以查看和下载SonataMediaBundle和Symfony 4中的路由

时间:2018-10-22 11:23:17

标签: symfony symfony4 sonata-media-bundle symfony-routing

我通过SonataAdminBundle和SonataMediaBundle使用Symfony 4(更精确的4.1)。

这是我的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

然后,即使我已被认证为ROLE_SUPER_ADMIN,我也总是得到AccessDeniedException。

该错误发生在vendor/sonata-project/media-bundle/src/Controller/MediaController.php中的downloadActionviewAction中。我一直在研究源代码,但找不到引发异常的原因。

1 个答案:

答案 0 :(得分:2)

经过研究,我找到了罪魁祸首并解决了问题。在这里,我想分享我的知识。

正如我在问题中提到的,异常是从以下位置抛出的:

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

在方法downloadActionviewAction中。满足以下条件:

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_ADMINROLE_SUPER_ADMIN来下载/查看媒体。

Gallery不会访问vendor/sonata-project/media-bundle/src/Controller/GalleryController.php的路由,因为sonata_media: resource: '@SonataMediaBundle/Resources/config/routing/media.xml' prefix: /admin/media 不会检查是否授予访问权限。

找到罪魁祸首之后,问题是选择哪种方法来解决问题

1)更改路由前缀:

security.yml

media中声明的路径现在覆盖ROLE_ADMIN,并且ROLE_SUPER_ADMINsecurity.yml可以访问路由。

缺点:如果要在管理员之外公开媒体怎么办?还有其他角色应该能够访问它们呢?

2)在access_control: - { path: ^/media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] } 中声明新路径:

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

现在,我们可以在管理员之外公开媒体。但是另一个问题仍然存在:如果其他角色需要访问媒体怎么办?

3)在SonataMedia的配置中配置另一种下载策略:

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

并调整路径:

<Grid>
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Customers}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Surname}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Age}" />
        </DataGrid.Columns>
        <DataGrid.ItemContainerStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <EventSetter Event="MouseDown" Handler="DataGridRow_MouseDown" />
            </Style>
        </DataGrid.ItemContainerStyle>
    </DataGrid>
</Grid>

现在,每个登录用户都可以访问媒体。这个解决方案对我有用。

但是,这并不是万能的菜谱。请查看官方文档中的security一章,以获取更多详细信息。