【问题标题】:Blazor JWT AuthenticationBlazor JWT 身份验证
【发布时间】:2020-06-16 20:37:01
【问题描述】:

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

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

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

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

谢谢。

【问题讨论】:

    标签: c# blazor


    【解决方案1】:

    前三段非常清晰正确。这就是你应该这样做的方式。我可以在这里发布一些代码 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,以便您的用户界面反映此更改等。

    祝你好运。

    希望对你有帮助……

    【讨论】:

    • 非常感谢您的意见。因此,根据我的配置开始,我可以忘记 IAccessTokenProvider。 HTTP 客户端标头中的自动令牌注入怎么样,我是否可以或应该仍然调查自定义 AuthorizationMessageHandler,否则如果没有 IAccessTokenProvider,此组件将无法使用?
    • 我想我会坚持使用 BaseAddressAuthorizationMessageHandler 和自定义 IAccessTokenProvider,因为它们的关系现在更清晰了。困扰我的最后一件事是获取访问令牌并将其存储在本地的实现。到目前为止我能想到的最好的方法是拥有一个全局身份验证服务,该服务将提供获取令牌、刷新它、存储的功能等等。 IAccessTokenProvider 和 AuthenticationStateProvider 都将在请求令牌时使用它,并且每当身份验证状态发生变化(如用户登录或退出)时都会收到通知。
    • 是的,这正是我的做法,一旦用户登录或注销并且令牌发生更改,身份验证服务中就会引发一个事件,导致 AuthenticationStateProvider 重新评估当前状态。所以现在我觉得我很好,非常感谢你的意见:)
    猜你喜欢
    • 2023-01-22
    • 2019-10-29
    • 1970-01-01
    • 2021-04-30
    • 2020-07-07
    • 2021-04-22
    • 2021-11-05
    • 2020-02-27
    • 2020-11-02
    相关资源
    最近更新 更多