我正在尝试找出使用Blazor(WASM)实现JWT身份验证的正确方法。 在阅读了文档之后,我对内置组件的工作原理有了一个想法,但是整体情况仍然不清楚。 因此,在我的场景中,我有一个将要使用的API服务器,API服务器可以发出JWT令牌,并且可以根据需要使用它们对端点进行身份验证。
所以现在我正试图找出每个组件的正确角色。 首先,我们有AuthenticationStateProvider,据我所知,此组件负责从服务器或本地存储的JWT令牌中获取JWT令牌,还可以在需要时处理令牌刷新?
现在,由于我将使用类型HTTP客户端,因此我将使用IHttpClientFactory,并且我还将具有AuthorizationMessageHandler来将令牌附加到所需的HTTP客户端实例。
当我尝试处理IAccessTokenProvider时,事情变得崩溃了,因为我知道,一旦创建HTTP客户端并即将发出HTTP请求,就会调用默认实现。 目前尚不清楚此IAccessTokenProvider将如何获取令牌。 因此,问题是我是否应该创建自己的IAccessTokenProvider实现,以及是否应该处理令牌。 正如我所说,我将不会使用任何内置的身份验证提供程序,而将拥有我自己的JWT身份验证系统。
谢谢。
答案 0 :(得分:2)
前三段非常清楚和正确。这就是您应该这样做的方式。我可以在此处发布一些代码段,以演示其在实践中的完成方式...
当我尝试处理IAccessTokenProvider时,事情对我来说是崩溃的,
难怪... IAccessTokenProvider在这里不相关。 IAccessTokenProvider是在WebAssembly Blazor App的新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));
}
}
这很好。但是当然,您可以创建一个仿照AuthorizationMessageHandler建模的自定义DelegatingHandler,或者更好的使用BaseAddressAuthorizationMessageHandler建模,因为您将使用IHttpClientFactory提供HttpClient服务。首先尝试不加任何修改地使用它们,如果不实际,请模拟它们的功能。
困扰我的最后一件事是获取访问令牌并将其存储在本地的实现。到目前为止,我能想到的最佳方法是拥有全局身份验证服务,该服务将提供获取令牌,刷新的功能它,存储等。当请求令牌时,IAccessTokenProvider和AuthenticationStateProvider都将使用它,并且只要身份验证状态发生变化(例如用户登录或注销),就会被通知。
完美...注意:应将Jwt令牌状态的更改通知AuthenticationStateProvider。例如,当您从Web Api端点获取新令牌时,您的代码应将其添加到本地存储,然后将更改通知CUSTOM AuthenticationStateProvider。如果您删除了Jwt令牌,您的代码还应通知AuthenticationStateProvider,以便您的用户界面将反映此更改,等等。
祝你好运。
希望这对您有帮助...