1

While owning/hosting a Web API 2 application, I am writing a desktop application where I need to download a .zip file based on certain criteria. I have come across two approaches and am not sure which is more secure and proper:

1) In the initial approach, I made a function call to my web api with the provided criteria. The API would create the zip file and return a specific path string. Then, I used the WebClient.DownloadFileAsync to download the related file from the path:

private async Task<bool> DownloadFile(SOME PARAMETER)
{
var result = false;
var _stopwatch = new Stopwatch();

try
{
    using (var _client = new WebClient())
    {
        // Returns the Uri of the file
        var downloadAddress = await GetDownloadFileAddress(SOME PARAMETER);

        if (!string.IsNullOrEmpty(downloadAddress))
        {
            // Some local path
            var downloadFilePath = "C:\MyLocalPath"

            _stopwatch.Start();

            _client.DownloadFileCompleted += wc_DownloadFileCompleted;
            _client.DownloadProgressChanged += wc_DownloadProgressChanged;
            _client.DownloadFileAsync(new Uri(downloadAddress), downloadFilePath);

            result = true;
        }
    }
}
catch (Exception ex)
{
    ModErrorHandler.HandleError(ex, MethodBase.GetCurrentMethod().Name, Application.ProductName);
}

return result;
}

I like the above because the files could be near a 1 gig and so I can display progress bar to show the download progress and also copy the file into a specific local path. However, I am concerned that it is not a secure way to pass the Uri openly(?!)

2) Then, I thought I could return the related file from the API directly. A sample code could be found here: How to return a file (FileContentResult) in ASP.NET WebAPI

The api authentication will now take care of security and invalid download requests. However, I am not sure if this is a wise approach for files that over 1gb. More importantly, I am not sure how to show the download progress in my progress bar and how to copy the file into a specific local path, both of which would be taken care of in the first approach.

Can someone advise which method is truly the correct way? And if 2, suggest a few hints for the questions that I have raised after?

amindomeniko
  • 417
  • 6
  • 23
  • 1
    Personally I'd go with `option 1`, sounds like it's already working and you have coded your application to work well that way (progress bar and such), if you are concerned about the security of the uri, you can always `encrypt` it in the `API` and `decrypt` it from your application. Or you could always store the uri in a database and just pass back the identity of the uri in the database back from the `API` and make a database call to get the uri. – Ryan Wilson Jan 11 '19 at 14:58
  • Interesting question. Obviously when downloading it through the API you have a bit more control about who gets to download it, since you decide when the file gets returned (you could for example first check on IP, some kind of secret, etc). But honestly, I don't think there's a big difference in security (as long as the rest of your application and API are secure at least). – Dnomyar96 Jan 11 '19 at 15:05
  • One is using WebClient and the other is using HttpRequest/HttpResponse. They are both Net Library methods. The WebClient is more sophisticated and is simpler to use in most cases. – jdweng Jan 11 '19 at 15:08

0 Answers0