如何仅向授权用户提供静态文件?

How do I serve static files only to authorized users?

我有一组 Excel 电子表格,我想在我的 ASP.NET 5 webapp 中仅向授权用户提供这些电子表格。

  1. 我应该将文件存储在哪里?我假设在 wwwroot 中(例如,wwwroot/files)。
  2. 如果在 wwwroot 中,如何只允许授权用户访问? (我想将它们作为来自控制器的 [Authorize] FileResult 提供,但这仍然使文件打开以通过我相信的 URL 直接访问。)
  3. 如何通过控制器中的 FileResult 操作引用 wwwroot 中的位置?

非常感谢!

是的,他们应该进去 wwwroot。目前没有内置方法来保护 wwwroot 目录。但是创建一个中间件模块来完成它非常简单。有一个简单易懂的教程 here.

如果您不熟悉中间件的开发,我发布了一个 GitHub 项目,展示了如何通过三个简单的步骤创建中间件。您可以下载项目here

您不需要控制器来访问静态文件。

在.net core中创建一个与wwwroot同级的专用目录www,并使用以下代码:

public HomeController(IHostingEnvironment hostingEnvironment)
{
    _hostingEnvironment = hostingEnvironment;
}

[Authorize(Roles = "SomeRole")]
public IActionResult Performance()
{
    return PhysicalFile(Path.Combine(_hostingEnvironment.ContentRootPath,
                                     "www", "MyStaticFile.pdf"), "application/pdf");
}

基于以下答案(对于 .netCore):static file authorization

这是一个非常简单的示例,但可以更改它以检查特定角色,并且可以将代码移出 Startup.cs 以获得更大的灵活性。

app.Use(async (context, next) =>
               {
                   if (!context.User.Identity.IsAuthenticated
                       && context.Request.Path.StartsWithSegments("/excelfiles"))
                   {
                       throw new Exception("Not authenticated");
                   }
                   await next.Invoke();
               });

如果您有登录表单 (Login.html),一个简单的解决方案是在用户未通过身份验证并且请求受保护资源(/protected 文件夹下的文件)时将用户重定向到登录页面。在 Startup.cs 中,在 Configure 方法中插入此代码:

app.Use(async (context, next) =>
{
    if (!context.User.Identity.IsAuthenticated && context.Request.Path.StartsWithSegments("/protected"))
    {
        context.Response.Redirect("/Login.html");
        return;
    }
    await next.Invoke();
});

检索文件时进行身份验证:

        app.UseStaticFiles(new StaticFileOptions()
        {
            OnPrepareResponse = (context) =>
            {
                if (!context.Context.User.Identity.IsAuthenticated && context.Context.Request.Path.StartsWithSegments("/excelfiles"))
                {
                    throw new Exception("Not authenticated");
                }
            }
        });