我正在尝试找出使用 Blazor (WASM) 实施 JWT 身份验证的正确方法。在浏览完文档后,我了解了内置组件的工作原理,但我仍然不清楚整个情况。因此,在我的场景中,我有一个将使用的 API 服务器,API 服务器可以颁发 JWT 令牌,并且它们可用于在需要时对端点进行身份验证。
所以现在我正在尝试找出每个组件的正确角色。首先,我们有 AuthenticationStateProvider,据我了解,该组件有责任从服务器获取 JWT 令牌,或者如果本地存储令牌,它还可以在需要时处理令牌刷新吗?
现在,由于我将使用类型化 HTTP 客户端,因此我将使用 IHttpClientFactory,同时我还将使用 AuthorizationMessageHandler 将令牌附加到所需的 HTTP 客户端实例。
当我尝试处理 IAccessTokenProvider 时,事情对我来说崩溃了,因为我知道一旦创建 HTTP 客户端并且即将发出 http 请求,就会调用默认实现。尚不清楚的是这个 IAccessTokenProvider 将如何获取令牌。所以问题是我是否应该创建自己的 IAccessTokenProvider 实现,如果是的话它应该如何处理令牌。正如我所说,我不会使用任何内置的身份验证提供程序,而是将拥有自己的 JWT 身份验证系统。
谢谢。
前三段非常清楚和正确。这就是你应该这样做的方式。我可以在这里发布一些代码片段来演示它在实践中是如何完成的......
当我尝试处理 IAccessTokenProvider 时,事情就崩溃了,
难怪... IAccessTokenProvider 在这里不相关。IAccessTokenProvider 是 WebAssembly Blazor 应用程序的新 JWT 令牌身份验证系统中使用的令牌提供程序。但是,如果您想自己实现 JWT 身份验证,则必须按照前三段中的描述进行操作......我可以这样总结:
上述过程还涉及 AuthenticationStateProvider 对象的实现,该对象使用身份验证状态进行更新,并通知订阅者(例如 CascadingAuthenticationState)身份验证状态已更改,在该过程结束时其他组件和对象会进行适应新的情况……你知道,重新渲染等等。
因此,您会看到,您已从 Web Api 收到 JWT 令牌,将其存储在本地存储中,读取并使用它。从本地存储读取 Jwt 令牌并解析它在很大程度上是 IAccessTokenProvider 所做的事情,但在新的身份验证系统中,并且由于您不使用该系统,因此 IAccessTokenProvider 不相关。
关于 HTTP 客户端标头中的自动令牌注入怎么样,我是否可以或应该仍然调查自定义 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));
}
}
Run Code Online (Sandbox Code Playgroud)
这完全没问题。当然,您可以创建一个模仿 AuthorizationMessageHandler 的自定义 DelegatingHandler,或者更好的是 BaseAddressAuthorizationMessageHandler,因为您将使用 IHttpClientFactory 来提供 HttpClient 服务。首先尝试在不进行任何修改的情况下使用它们,如果不实用,只需模拟它们的功能。
最后困扰我的是获取访问令牌并将其存储在本地的实现。到目前为止我能想到的最好的方法是有一个全局身份验证服务,该服务将提供获取令牌、刷新令牌、存储令牌的功能等。 IAccessTokenProvider 和 AuthenticationStateProvider 都会在请求令牌时使用它,并且每当身份验证状态发生变化(例如用户登录或注销)时都会收到通知。
完美... 注意:应将 Jwt 令牌状态的更改通知 AuthenticationStateProvider。例如,当您从 Web Api 端点获取新令牌时,您的代码应将其添加到本地存储,然后将更改通知 CUSTOM AuthenticationStateProvider。如果您删除 Jwt 令牌,您的代码还应该通知 AuthenticationStateProvider,以便您的用户界面将反映此更改等。
祝你好运。
希望这可以帮助...