phpsymfonysonata-media-bundle

Prevent direct access to uploaded files only for unauthorized users - Symfony


I am trying to give direct access to uploaded files only for logged in users in my website for security concerns. I tried this configuration but it seems to be working on download image.

This is my Twig file code where I am showing the image.

{% if(req.media!='') %}
      <a href="{% path req.media, 'reference' %}"
      data-fancybox class="fancybox">
       <img src="{% path (req.media), 'reference' %}" alt="" width="70px"
        height="70px"/>
      </a>
{% endif %}

configuration for sonata media below.

Sonata_media.yml

sonata_media:
# if you don't use default namespace configuration
#class:
#    media: MyVendor\MediaBundle\Entity\Media
#    gallery: MyVendor\MediaBundle\Entity\Gallery
#    gallery_has_media: MyVendor\MediaBundle\Entity\GalleryHasMedia
db_driver: doctrine_orm # or doctrine_mongodb, doctrine_phpcr it is mandatory to choose one here
default_context: default # you need to set a context
contexts:
    default:  # the default context is mandatory
        download:
            strategy: sonata.media.security.forbidden_strategy
        providers:
            #- sonata.media.provider.dailymotion
            #- sonata.media.provider.youtube
            - sonata.media.provider.image
            - sonata.media.provider.file
            #- sonata.media.provider.vimeo

Solution

  • I followed these steps to achieve this requirement.

    1. Created a function and added its route in firewall, so anonymous users cannot go to that path.
    2. Created a route to set its path.
    3. Got media id in the function and did the functionality to return the file.
    4. Called the function by its path with parameter mediaId instead of calling direct media in twig.

    Here is the code.

    security.yml

    - { path: ^/user(.*), roles: ROLE_DASHBOARD_USER }
    

    routing.yml

    cms_direct_access_uploaded_files:
    path:     /user/image-return/{fileId}
    defaults: { _controller: CMSFrontUserBundle:Dashboard:DirectAccessUploadedMedia }
    

    Controller

        public function DirectAccessUploadedMediaAction(Request $request,$fileId = null){
        $user = $this->getUser();
        if(!empty($user)){
            $DM = $this->getDoctrineManager();
            $media = $DM->getRepository('ApplicationSonataMediaBundle:Media')->find($fileId);
            if(!empty($media)) {
                $provider   = $this->container->get( $media->getProviderName() );
                $format     = $provider->getFormatName( $media, 'reference' );
                $url        = $provider->generatePublicUrl( $media, $format );
                $ext = pathinfo($url, PATHINFO_EXTENSION);
                $returnFile = $_SERVER['DOCUMENT_ROOT'] .'/web'. $url;
                if (file_exists($returnFile)) {
                    if($ext == 'pdf'){
                        header("Content-Type: application/pdf");
                    }else{
                        header("Content-Type: image/jpeg");
                    }
                    header('Expires: 0');
                    header('Cache-Control: must-revalidate');
                    header('Pragma: public');
                    header('Content-Length: ' . filesize($returnFile));
                    readfile($returnFile);
                    exit;
                }
            }else{
                throw $this->createAccessDeniedException('Forbidden!');
            }
        }else{
            throw $this->createAccessDeniedException('Forbidden!');
        }
    }
    

    Twig

    {{ url('homepage') }}user/image-return/{{ req.media.id }}