如何通过.net core 5.0 API控制对静态文件的访问



我有一个API和一个客户端应用程序(Blazor web assembly)分别。客户端应用程序通过Azure活动目录对用户进行身份验证。在客户端中,当我通过API保存任何文件时,我使用在Startup.cs上配置的静态文件,例如:

app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(@"c:", @"Resources")),
RequestPath = new PathString("/secureFile"),
});

问题是客户端应用程序工作正常。但如果有人检查Html并获取图像源他们可以直接通过浏览器访问文件,如https://localhost:44397/secureFile/profile.jpg

另一方面,因为我使用Azure活动目录登录,API不保存任何用户信息。这就是为什么我不能使用这样的场景:

app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(@"c:", @"Resources")),
RequestPath = new PathString("/secureFile"),
OnPrepareResponse = ctx =>
{                   
if (!ctx.Context.User.Identity.IsAuthenticated)
{
// respond HTTP 401 Unauthorized.
ctx.Context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
ctx.Context.Response.ContentLength = 0;
ctx.Context.Response.Body = Stream.Null;
// ctx.Context.Response.Redirect("/")
}
}
});

这里!ctx.Context.User.Identity.IsAuthenticated总是假的,即使客户端应用程序正在调用。

可能客户端应用程序正在通过身份验证:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Audience = Configuration["AAD:ResourceId"];
options.Authority = $"{Configuration["AAD:InstanceId"]}{Configuration["AAD:TenantId"]}";
});

我的目标是在客户机应用程序调用图像源时允许访问https://localhost:44397/secureFile/profile.jpg。但是如果有人直接通过URL调用,应该阻止。

任何线索都会对我有很大帮助。我已经遵循了这篇文章,但在我的场景中没有使用,因为我使用的是AAD登录。

您提到"API不保存任何用户信息",但是,无论身份验证流程如何,必须为单个请求临时建立一些身份验证信息,以便评估授权。

在您列出的示例代码中,您正在调用对HttpContext用户声明主体的检查,以查看用户是否经过身份验证,并且您提到它总是返回为false,即使它来自您的客户端应用程序。这里值得注意的是something必须在执行授权之前调用应用程序中的身份验证流。因为在StaticFileMiddleware中没有任何东西固有地做这个,所以它可能永远不会在请求期间发生。

您可以通过使用ChallengeAsync()方法自己调用该身份验证流,该方法旨在使用默认挑战方案"挑战"当前请求。当未经身份验证的用户请求需要身份验证的端点时,可能会发出身份验证挑战:

https://learn.microsoft.com/en us/dotnet/api/microsoft.aspnetcore.authentication.authenticationhttpcontextextensions.challengeasync?view=aspnetcore - 6.0

您可能需要为您的特定情况定制行为,特别是如果您必须适应多种方案,但是一般的起点将是添加using Microsoft.AspNetCore.Authentication;以确保HttpContext扩展可用,然后在您的流中添加对await ctx.Context.ChallengeAsync()的相应调用,如果用户未经过身份验证。

运行后,您可以再次检查用户是否经过身份验证,以及他们是否满足您希望对安全静态文件具有的授权要求。

最新更新