前三段非常清晰正确。这就是你应该这样做的方式。我可以在这里发布一些代码 sn-p 来演示它是如何在实践中完成的......
当我尝试处理 IAccessTokenProvider 时,事情就崩溃了,
难怪... IAccessTokenProvider 在这里不相关。 IAccessTokenProvider 是用于 WebAssembly Blazor 应用程序的新 JWT 令牌身份验证系统中的令牌提供程序。但是如果您想自己实现 JWT 身份验证,则必须按照前三段中的说明进行操作……我可以这样总结:
- 当用户首次访问受保护的 Web api 端点并且他没有经过身份验证(或注册)时,他会被重定向到相关页面,键入他的凭据等,然后将其传递给专用于身份验证的 Web Api 端点用户(必要时注册等),之后调用的操作方法生成 JWT 令牌,并将其发送回在浏览器上运行的 WebAssembly Blazor 应用程序。您应该存储 JWT 令牌(可能在本地存储中),并在您执行 HTTP 调用时检索它(将 JWT 令牌添加到请求的标头中)。
上述过程还涉及到AuthenticationStateProvider对象的实现,它随着认证状态的更新,并通知订阅者,例如CascadingAuthenticationState,认证状态已经改变,最后处理其他组件和对象让自己适应新情况……你知道,重新渲染等等。
因此,您已从 Web Api 收到 JWT 令牌,将其存储在本地存储中,读取并使用它。从本地存储读取 Jwt Token 并对其进行解析,很大程度上是 IAccessTokenProvider 所做的,但在新的身份验证系统中,由于您不使用此系统,因此 IAccessTokenProvider 不相关。
HTTP 客户端标头中的自动 Token 注入怎么样,我是否可以或应该仍然调查自定义 AuthorizationMessageHandler,否则如果没有 IAccessTokenProvider,此组件将无法使用?
您可以将您的 Jwt 令牌添加到每个 HTTP 调用,如下所示:
@code {
Customer[] customers;
protected override async Task OnInitializedAsync()
{
// Read the token from the local storage
var token = await TokenProvider.GetTokenAsync();
customers = await Http.GetFromJsonAsync<Customer[]>(
"api/customers",
new AuthenticationHeaderValue("Bearer", token));
}
}
这很好。但当然,您可以创建一个仿照 AuthorizationMessageHandler 的自定义 DelegatingHandler,或者更好的是 BaseAddressAuthorizationMessageHandler,因为您将使用 IHttpClientFactory 来提供您的 HttpClient 服务。首先尝试尝试在不进行任何修改的情况下使用它们,如果不实用,只需模拟它们的功能。
最后困扰我的是获取访问令牌并将其存储在本地的实现。到目前为止我能想到的最好的方法是拥有一个全局身份验证服务,该服务将提供获取令牌的功能,刷新它,存储等。 IAccessTokenProvider 和 AuthenticationStateProvider 都将在请求令牌时使用它,并且每当身份验证状态发生更改(如用户登录或注销)时都会收到通知。
完美... 注意:应通知 AuthenticationStateProvider Jwt 令牌状态的变化。例如,当您从 Web Api 端点获取新令牌时,您的代码应将其添加到本地存储,然后将更改通知 CUSTOM AuthenticationStateProvider。如果您删除 Jwt 令牌,您的代码还应通知 AuthenticationStateProvider,以便您的用户界面反映此更改等。
祝你好运。
希望对你有帮助……