Blazor JWT 身份验证

Nul*_*nce 4 c# blazor

我正在尝试找出使用 Blazor (WASM) 实施 JWT 身份验证的正确方法。在浏览完文档后,我了解了内置组件的工作原理,但我仍然不清楚整个情况。因此,在我的场景中,我有一个将使用的 API 服务器,API 服务器可以颁发 JWT 令牌,并且它们可用于在需要时对端点进行身份验证。

所以现在我正在尝试找出每个组件的正确角色。首先,我们有 AuthenticationStateProvider,据我了解,该组件有责任从服务器获取 JWT 令牌,或者如果本地存储令牌,它还可以在需要时处理令牌刷新吗?

现在,由于我将使用类型化 HTTP 客户端,因此我将使用 IHttpClientFactory,同时我还将使用 AuthorizationMessageHandler 将令牌附加到所需的 HTTP 客户端实例。

当我尝试处理 IAccessTokenProvider 时,事情对我来说崩溃了,因为我知道一旦创建 HTTP 客户端并且即将发出 http 请求,就会调用默认实现。尚不清楚的是这个 IAccessTokenProvider 将如何获取令牌。所以问题是我是否应该创建自己的 IAccessTokenProvider 实现,如果是的话它应该如何处理令牌。正如我所说,我不会使用任何内置的身份验证提供程序,而是将拥有自己的 JWT 身份验证系统。

谢谢。

Isa*_*aac 7

前三段非常清楚和正确。这就是你应该这样做的方式。我可以在这里发布一些代码片段来演示它在实践中是如何完成的......

当我尝试处理 IAccessTokenProvider 时,事情就崩溃了,

难怪... IAccessTokenProvider 在这里不相关。IAccessTokenProvider 是 WebAssembly Blazor 应用程序的新 JWT 令牌身份验证系统中使用的令牌提供程序。但是,如果您想自己实现 JWT 身份验证,则必须按照前三段中的描述进行操作......我可以这样总结:

  • 当用户首次访问受保护的 Web API 端点并且未经过身份验证(或注册)时,他会被重定向到相关页面,输入他的凭据等,您将其传递到专用于对用户进行身份验证的 Web Api 端点(必要时进行注册等),之后调用的操作方法会生成 JWT 令牌,并将其发送回浏览器上运行的 WebAssembly Blazor 应用程序。您应该存储 JWT 令牌(可能在本地存储中),并在执行 HTTP 调用时检索它(将 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,以便您的用户界面将反映此更改等。

祝你好运。

希望这可以帮助...