ASP.NET MVC网站下虚拟目录中IIS内容的身份验证

ASP.NET MVC网站下虚拟目录中IIS内容的身份验证,asp.net,asp.net-mvc,security,authentication,virtual-directory,Asp.net,Asp.net Mvc,Security,Authentication,Virtual Directory,我有一个ASP.NET MVC应用程序,我将上载的内容文件存储在虚拟目录中。此虚拟目录位于IIS中我的MVC网站的正下方 我的问题是虚拟目录允许匿名访问。无论是否登录,任何人都可以键入指向我的虚拟目录的公共URL并读取其中的文件。是否可以以强制对此虚拟目录的任何请求在允许访问之前运行身份验证/授权例程的方式配置IIS(或其他内容) 这是我可以在我的网站的web.config中配置的东西,还是在这种情况下请求从未命中任何服务器端代码?如果它从未命中服务器端代码(并将请求直接提供给IIS),我如何更

我有一个ASP.NET MVC应用程序,我将上载的内容文件存储在虚拟目录中。此虚拟目录位于IIS中我的MVC网站的正下方

我的问题是虚拟目录允许匿名访问。无论是否登录,任何人都可以键入指向我的虚拟目录的公共URL并读取其中的文件。是否可以以强制对此虚拟目录的任何请求在允许访问之前运行身份验证/授权例程的方式配置IIS(或其他内容)

这是我可以在我的网站的web.config中配置的东西,还是在这种情况下请求从未命中任何服务器端代码?如果它从未命中服务器端代码(并将请求直接提供给IIS),我如何更改实现以要求我的站点进行身份验证/授权,然后为我的文件提供服务


谢谢你的帮助

如果您运行的是具有集成身份验证的IIS 7或更高版本,则上载的内容将通过ASP.NET运行时运行,因此所有正常的身份验证技巧都有效--只需向文件夹中添加一个web.config以加强安全性即可


IIS 6或更早版本提出了不同的挑战。更好的方法是使用HTTP处理程序“前置”文件,该处理程序将文件从文件夹中抓取出来,这样您的文件就可以受到运行时的保护。

我不知道您是如何请求的。但是,我知道一种方法,你可以用另一种方法来做这件事。也许对你有用

其想法是将安全文件存储在一个无法从web获得的文件夹(不是虚拟目录)中。然后,在控制器上有一个方法,如
Controllers/DownloadController.cs
,用于处理用户身份验证和文件服务。下面是一个示例方法,可以从
c:\myfiles
检索文件:

控制器/DownloadController.cs(仅限操作方法):


fileFolder
变量应在类级别定义。我把它拿出来是因为它弄乱了代码格式。:)

谢谢。我正在运行IIS 7,并将此部分添加到:结果是,在身份验证之前,我在登录页面上丢失了CSS(这是一个好迹象),但是我仍然能够在与web.config相同的根目录下访问VD中的内容文件。有什么想法吗?VD是一个独立的应用程序,所以它需要自己的web.config。我还没有尝试过这个场景,所以我不确定它是否会接受您的身份验证。很有趣。我想避免使用处理程序,但这可能是我唯一的选择。一个问题是,当返回的“文件”是图像时,它是否会像用户单击图像一样在浏览器中打开,还是会以图像作为下载内容开始文件下载。我希望是前者。谢谢。如果您想让它像下载一样运行,只需在返回文件(…)行中添加第三个参数。我将更新代码以给出一个示例。谢谢!我来试试,我得做个调整。FileResult的第一个参数必须是FileStream,才能工作。所以我的看起来像是返回文件(新文件流(Path.Combine(fileFolder,filename)),contentType);
[Authorize]
public FileResult Download(string filename)
{
    //get content type from file extension
    var contentType = getContentTypeFromExtension(filename);

    //return file with filename as third argument to 
    //   trigger browser's download bahavior
    return File(Path.Combine(fileFolder, filename), contentType, filename);
}

[Authorize]
public FileResult Open(string filename)
{
    //get content type from file extension
    var contentType = getContentTypeFromExtension(filename);

    //return file without download filename so that 
    //   the file is opened in browser (if possible)
    return File(Path.Combine(fileFolder, filename), contentType);
}

//method to get content type of file from registry using file extension
static string getContentTypeFromExtension (string fileName)
{
    string contentType = "application/unknown";
    string ext = System.IO.Path.GetExtension(fileName).ToLower();
    Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
    if (regKey != null && regKey.GetValue("Content Type") != null)
        contentType = regKey.GetValue("Content Type").ToString();
    return contentType;
}