ASP.NET MVC中的模拟

Ema*_*mad 6 security asp.net-mvc impersonation

我有一个需要从安全位置读取文件的Action,所以我必须使用模拟来读取文件.

此代码工作原理:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult DirectDownload(Guid id)
{
    if (Impersonator.ImpersonateValidUser())
    {
        try
        {
            var path = "path to file";
            if (!System.IO.File.Exists(path))
            {
                return View("filenotfound");
            }

            var bytes = System.IO.File.ReadAllBytes(path);
            return File(bytes, "application/octet-stream", "FileName");
        }
        catch (Exception e)
        {
            Log.Exception(e);
        }finally
        {
            Impersonator.UndoImpersonation();
        }
    }
    return View("filenotfound");
}
Run Code Online (Sandbox Code Playgroud)

上面代码的唯一问题是我必须将整个文件读入内存,我将处理非常大的文件,所以这不是一个好的解决方案.但如果我更换这两行:

var bytes = System.IO.File.ReadAllBytes(path);
return File(bytes, "application/octet-stream", "FileName");
Run Code Online (Sandbox Code Playgroud)

有了这个:

return File(path, "application/octet-stream", "FileName");
Run Code Online (Sandbox Code Playgroud)

它不起作用,我收到错误消息:

访问路径'c:\ projects\uploads\1\aa2bcbe7-ea99-499d-add8-c1fdac561b0e\Untitled 2.csv'被拒绝.

我想使用带有路径的文件结果,当我已经"撤消"模拟时,尝试稍后在请求管道中打开文件.

请记住,模拟代码有效,因为我可以读取bytes数组中的文件.我想做的是将文件流式传输到客户端.

知道如何解决这个问题吗?

提前致谢.

Dar*_*rov 5

您可以尝试编写自定义FilePathResult

public class ImpersonatingFileResult : FilePathResult
{
    public ImpersonatingFileResult(string fileName, string contentType) 
        : base(fileName, contentType)
    { }

    protected override void WriteFile(HttpResponseBase response)
    {
        // TODO : Start impersonation
        response.TransmitFile(FileName);
        // TODO : Rollback impersonation
    }
}
Run Code Online (Sandbox Code Playgroud)

并在您的控制器中:

return new ImpersonatingFileResult(path, "application/octet-stream");
Run Code Online (Sandbox Code Playgroud)