如何在来自核心托管的 blazor 网络程序集的图像 src 请求中对用户进行身份验证

问题描述

在 Blazor Core Hosted Webassembly 应用程序中调用认 API 时,我使用预配置的 HttpClient,其中包含安全令牌的标头。这意味着在服务器上我可以访问哪个用户登录

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

我制作了一个图像控制器来处理调用,它可以是标准的 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 auth cookie:

[Authorize(AuthenticationSchemes = "Identity.Application")]

完成此操作后,请求将被验证。

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

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

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

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

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

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