2016-09-16 48 views
0

我目前在“下载文件”实施使用Web API的工作2.允许URI的Web API调用

然而,作为可下载不存储在数据库中的文件的完整的文件路径,我我传入完整的文件路径作为标识参数。

看来这种方法的问题在于filePath包含对URI无效的字符......有没有人有任何建议来解决这个问题或替代方法?

下载文件的方法:

[HttpGet] 
    [Route("Files/{*filePath}")] 
    public HttpResponseMessage Get([FromUri]string filePath) 
    { 
     try 
     { 
      var file = new FileInfo(filePath); 

      byte[] bytes = System.IO.File.ReadAllBytes(filePath); 

      var result = Request.CreateResponse(HttpStatusCode.OK); 

      result.Content = new ByteArrayContent(bytes); 
      result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
      result.Content.Headers.ContentDisposition.FileName = file.Name + file.Extension; 

      return result; 

     } 
     catch(Exception ex) 
     { 
      return Request.CreateResponse(HttpStatusCode.InternalServerError, ex); 
     } 
    } 

回答

0

要求客户把完整路径的URI(即使它被编码,以便它包含唯一有效字符的URI)意味着你可能会地方出版这些路径...这不是几个原因一个伟大的想法:

  1. 安全 - full Path Disclosure和相关Relative Path Traversal
    1. 什么是阻止某人通过敏感文件的路径(例如你的web.config文件),并可能获取有助于攻击你的系统的信息?
  2. 可维护性
    1. 客户端可以保持重用或分发URI的副本 - 如果文件路径改变会发生什么?有关这个主题的一些相关的谈话在这里:Cool URIs don't change

我的建议 - 你不必把自己的文件在数据库中,而是把文件的列表在数据库中,并使用一个唯一的标识符在URL中(例如,可能是slugGUID)。在数据库中查找标识符以发现路径,然后返回该文件。

这保证:

  1. 没有人可以读取一个文件,你还没有建立索引,确定是安全的下载
  2. 如果你将可以更新文件的数据库和客户端的URI不会改变
  3. ,并为你原来的问题作出回应,你可以很容易地确保唯一标识符仅由URI的安全角色

一旦你的数据库,随着时间的推移你也可能对维护数据库中的其他元数据非常有用,例如谁上传文件,何时下载,何时下载,以及何时等。

+0

感谢您的详细回复,Chris!你在那里展示的一些很好/有用的观点。您的建议的一个问题是保持数据库最新...如果新文件被添加到源文件夹,移动或删除,数据库将不得不手动更新... – Tomuke

+0

根据API的性质和数量客户可能是一件好事 - 例如如果您有50个API客户端并且您移动了一个文件,您是否愿意更新50个客户端或一个数据库条目?如果你可以用更多关于客户端 - 服务器关系的信息来更新你的问题(有多少客户端,他们如何获得放入api URI的路径知识等),这将有助于提供更好的答案。 –