3

I have an MVC 5 application that allows users to download files that are stored in the database. I am using the FileContentResult action method to do this.

I can restrict access to this method throughout the application, but a smart user can figure out the action URL and paste something like this (localhost:50000/Home/FileDownload?id=13) into their browser and have access to download any file by just changing the parameter.

I want to restrict users from doing this. Only allow the Administrator role AND users that have a specific permission that can only be determined by a database call to download files.

What I am looking for is that If an user uses the URL to download a file and does not have the proper permissions, I want to redirect the user with a message.

I would like to do something like the code below or similar, but I get the following error: Cannot implicitly convert type 'System.Web.Mvc.RedirectToRouteResult' to 'System.Web.Mvc.FileContentResult'

I understand that I can not use return RedirectToAction("Index") here, just looking for some ideas on how to handle this problem.

    public FileContentResult FileDownload(int id)
    {
        //Check user has file download permission
        bool UserHasPermission = Convert.ToInt32(context.CheckUserHasFileDownloadPermission(id)) == 0 ? false : true;

        if (User.IsInRole("Administrator") || UserHasPermission)
        {
            //declare byte array to get file content from database and string to store file name
            byte[] fileData;
            string fileName;
            //create object of LINQ to SQL class

            //using LINQ expression to get record from database for given id value
            var record = from p in context.UploadedFiles
                         where p.Id == id
                         select p;
            //only one record will be returned from database as expression uses condtion on primary field
            //so get first record from returned values and retrive file content (binary) and filename
            fileData = (byte[])record.First().FileData.ToArray();
            fileName = record.First().FileName;
            //return file and provide byte file content and file name

            return File(fileData, "text", fileName);
        }
        else
        {
            TempData["Message"] = "Record not found";

            return RedirectToAction("Index");
        }           
    }
4

1 に答える 1