0

我正在尝试对我的 Web 应用程序中的文件夹进行简单的保护。从文档中看起来非常简单。然而,它对我不起作用。

我有一个剃须刀页面,其中有一个名为 keys 的文件夹,其中有一些文本文件。从文档:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/razor-pages-authorization?view=aspnetcore-3.1

我努力了:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages(options => {
            options.Conventions.AuthorizeFolder("/keys");
        });
    }


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

        ....
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();
        app.UseAuthentication();

然而,一旦我启动应用程序并在浏览器上输入:

https://localhost:44312/keys/clear.txt

服务器肯定会发回页面。有什么线索吗?

在此处输入图像描述

4

2 回答 2

1

你在卡梅伦的回答下的评论让我有点困惑,所以我的回答可能不是你想做的。

无论如何,您可以使用app.UseStaticFiles()添加中间件来保护该文件夹。由于它是中间件,因此您需要将其插入管道中的正确位置才能使其工作。这是完整的Configure方法Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();

    // Notice that this is the second time we're calling UseStaticFiles().
    // The first call is to configure CSS and things to be served.
    // This is deliberately called after UseAuthentication().
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            if (ctx.Context.Request.Path.StartsWithSegments("/keys"))
            {
                // As the files are sensitive, don't cache a response.
                ctx.Context.Response.Headers.Add("Cache-Control", "no-store");

                if (!ctx.Context.User.Identity.IsAuthenticated)
                {
                    ctx.Context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    ctx.Context.Response.ContentLength = 0;
                    ctx.Context.Response.Body = Stream.Null;
                }
            }
        },
        // It's the combination of the `FileProvider` and `RequestPath` that 
        // maps the `MyKeys` physical folder to the `/keys` path.
        FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "MyKeys")),
        RequestPath = "/keys"
    });

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

在上面的示例中,MyKeys是项目根目录下的文件夹,并且/keys是用于请求文件的路径:

ProjectName
| wwwroot
  | css
  | etc
| Pages
  | your razor pages
| MyKeys
  | clear.txt

如果用户未通过身份验证,他们将收到 401 响应。我们故意不缓存结果,因为文件很敏感。当然,您可以在这里做更多的事情,例如要求用户具有特定角色,或者如果他们没有登录则重定向他们。这取决于您。

于 2020-09-29T17:16:00.727 回答
0

该文档提到保护由 ASP.NET Core 处理的文件夹中的路由,而不是文件系统上的文件。如果您需要保护资源,那么您应该编写资源处理程序来提供文件并保护路由和/或控制器。

它应该是这样的:

[Authorize]
public ResourceController : ControllerBase {
  // Other Protected Resources
  
  [HttpGet("keys/clear")]
  public IActionResult Clear() {
    var file = Path.Combine("secure/path", "clear.txt");
    return PhysicalFile(file, "text/plain");
  }
}

请注意,由于您使用的是资源处理程序,因此您可以将 clear.txt 文件移动到另一个不可公开访问的目录。您的应用程序用户需要阅读它。

如果应用程序在 IIS 中运行,则该文件夹需要具有 IIS 应用程序池标识的读取权限。如果它在 Linux 上运行,那么您需要向运行服务器的用户授予读取权限。

于 2020-09-29T16:09:50.217 回答