如何根据来自核心托管 Blazor Web 程序集的图像 src 请求对用户进行身份验证

How to authenticate user on image src request from core hosted blazor web assembly

在 Blazor Core 托管 Webassembly 应用程序中调用默认值 API 时,我使用预配置的 HttpClient,其中包括 headers 作为安全令牌。这意味着在我有权访问哪个用户登录的服务器上。

但是,当使用 src 属性 将图像加载到 img 标签时,这不会使用 HttpClient,因此 header 不会附加到 get 请求。如果您想从服务器端提供静态 public 图像(例如徽标、品牌形象、图标等),这很好,但是您如何验证此请求以便用户只能获取自己的图像?

我制作了一个图像控制器来处理调用,它可以是标准 MVC 控制器或 API 控制器,并在 GetImage/{id} 方法上放置了一个 [Authorize] 属性,但是我不知道如何让浏览器进行身份验证(我收到 401,即使用户已登录到应用程序)

在 MVC 站点中,这通常由随浏览器请求一起发送的身份验证 cookie 处理,但 Blazor 不会设置此 cookie。

我可以使用 HttpClient 下载图像,将其转换为 base64 并使用该 base64 字符串设置 img 标签的内容,但这会绕过浏览器缓存并且看起来不必要地复杂,因为我随后需要处理所有这些传输和缓存等在客户端手动进行。

验证此浏览器触发的获取请求的最佳方法是什么?我可以手动设置一个 cookie 来执行此操作吗?

Blazor Core Hosted 中的身份服务器设置了一个身份验证 Cookie。但是,默认情况下,这不用于使用 [Authorize] 属性对 MVC 请求进行身份验证。

您可以通过将 Identity.Application 方案添加到装饰器上的 AuthenticationSchemes 来设置 [Authorize] 属性以使用 Identity Server 身份验证 cookie:

[授权(AuthenticationSchemes = "Identity.Application")]

完成此操作后,请求将通过身份验证。

但是,与 Blazor AIP 调用相比,此方法意味着在 MVC 控制器中获取 UserId 的方式略有不同。

在从 HttpClient 发出的调用中,我从 HttpContextAccessor 获得了 UserId

var userId = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier)

当请求通过 MVC 控制器时,此 returns 为 null,因此我改为通过 UserManager 获取 UserId:

           var userName = _httpContextAccessor?.HttpContext?.User?.Identity?.Name;
           var user = await _userManager.FindByEmailAsync(userName);
           var userId = theUser.Id;

这似乎可行,但如果有更好的方法,我将很高兴听到。