【问题标题】:Deny access to anonymous users not working on Razor pages拒绝不在 Razor 页面上工作的匿名用户访问
【发布时间】:2021-01-15 06:53:56
【问题描述】:

我正在尝试对我的 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

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

【问题讨论】:

    标签: asp.net-mvc razor-pages


    【解决方案1】:

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

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

    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 响应。我们故意不缓存结果,因为文件很敏感。当然,您可以在这里做更多的事情,例如要求用户具有特定角色,或者如果他们没有登录则重定向他们。这取决于您。

    【讨论】:

    • 谢谢!我想知道我是否可以将这些文件放在服务器中而不是在 wwwroot 下。
    • @gmmo 没问题。 :)
    【解决方案2】:

    文档提到保护由 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 上运行,那么您需要向运行服务器的用户授予读取权限。

    【讨论】:

    • 我该怎么做?我真的不希望公共目录中的这些文件,但我也不希望它们成为编译的一部分。我发现从服务器读取文件的唯一 API 的问题是使用类似:keysRootFolder = Path.Combine(webHostEnvironment.WebRootPath, "keys");这仅适用于 wwwroot 中的文件。我想知道如何读取不在 wwwroot 中的文件。谢谢!
    • 我已更新我的答案以更改为任意“安全”路径。您需要授予 IIS 应用程序池或运行 ASP.NET Core 的用户对此目录的读取权限。
    • 如何编写自定义处理程序?我看到你的答案,但我不明白。我看不到文档的链接可以做到这一点。我应该把你刚刚粘贴的那段代码放在哪里?
    猜你喜欢
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    相关资源
    最近更新 更多