Blazor JWT身份验证

时间:2020-06-16 09:23:31

标签: c# blazor

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

所以现在我正试图找出每个组件的正确角色。 首先,我们有AuthenticationStateProvider,据我所知,此组件负责从服务器或本地存储的JWT令牌中获取JWT令牌,还可以在需要时处理令牌刷新?

现在,由于我将使用类型HTTP客户端,因此我将使用IHttpClientFactory,并且我还将具有AuthorizationMessageHandler来将令牌附加到所需的HTTP客户端实例。

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

谢谢。

1 个答案:

答案 0 :(得分:2)

前三段非常清楚和正确。这就是您应该这样做的方式。我可以在此处发布一些代码段,以演示其在实践中的完成方式...

当我尝试处理IAccessTokenProvider时,事情对我来说是崩溃的,

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

  • 当用户首次访问受保护的Web api端点并且未通过身份验证(或注册)时,他将被重定向到相关页面,键入其凭据等,您将其传递到专用于身份验证的Web Api端点用户(必要时进行注册等),然后调用的操作方法将产生JWT令牌,并将其发送回在浏览器上运行的WebAssembly Blazor App。您应该存储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));
    }
}

这很好。但是当然,您可以创建一个仿照AuthorizationMessageHandler建模的自定义DelegatingHandler,或者更好的使用BaseAddressAuthorizationMessageHandler建模,因为您将使用IHttpClientFactory提供HttpClient服务。首先尝试不加任何修改地使用它们,如果不实际,请模拟它们的功能。

困扰我的最后一件事是获取访问令牌并将其存储在本地的实现。到目前为止,我能想到的最佳方法是拥有全局身份验证服务,该服务将提供获取令牌,刷新的功能它,存储等。当请求令牌时,IAccessTokenProvider和AuthenticationStateProvider都将使用它,并且只要身份验证状态发生变化(例如用户登录或注销),就会被通知。

完美...注意:应将Jwt令牌状态的更改通知AuthenticationStateProvider。例如,当您从Web Api端点获取新令牌时,您的代码应将其添加到本地存储,然后将更改通知CUSTOM AuthenticationStateProvider。如果您删除了Jwt令牌,您的代码还应通知AuthenticationStateProvider,以便您的用户界面将反映此更改,等等。

祝你好运。

希望这对您有帮助...

相关问题