Blazor WebAssembly SignalR 身份验证

And*_*rew 6 authentication signalr webassembly blazor

我很想看到一个关于如何使用 Blazor 的 WebAssembly 风格向 SignalR 集线器连接添加身份验证的示例。我的 dotnet 版本是 3.1.300。

我可以按照以下步骤获得开放的、未经身份验证的 SignalR 连接:https ://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr-blazor-webassembly?view = aspnetcore-3.1 & tabs = visual-工作室

我发现的所有教程看起来都比较旧或者是针对服务器托管类型的,并且不使用内置模板。

我已使用适当的模板和这些说明(包括数据库)向后端的其余部分添加了身份验证:https : //docs.microsoft.com/en-us/aspnet/core/security/blazor/?view= aspnetcore-3.1

但是每次我将 [Authenticate] 添加到聊天中心时,都会返回一个错误。有没有办法扩展第一个教程,我们可以验证在那里创建的集线器?连接到内置的 ASP.NET 系统会很棒,但我可以将令牌作为附加参数传入并自己完成,如果这是最好的。在这种情况下,我需要学习如何从 Blazor WebAssembly 中获取令牌,然后在服务器上的某个地方查找它。这似乎是错误的,但作为替代方案,它基本上可以满足我的需求。

有各种各样的半解决方案,或者是为旧版本设计的,但没有什么可以建立在 MS 提供的股票教程之上。

更新:按照本新闻稿https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-2-release-now-available/ 中的提示,我现在可以从内部获取令牌剃刀页面,并将其注入标题。我想这很好??但是,我如何获得它并在服务器上使用它呢?

这是剃刀代码的片段:

protected override async Task OnInitializedAsync()
{
    var httpClient = new HttpClient();
    httpClient.BaseAddress = new Uri(UriHelper.BaseUri);

    var tokenResult = await AuthenticationService.RequestAccessToken();

    if (tokenResult.TryGetToken(out var token))
    {
        httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token.Value}");

        hubConnection = new HubConnectionBuilder()
            .WithUrl(UriHelper.ToAbsoluteUri("/chatHub"), options =>
            {
                options.AccessTokenProvider = () => Task.FromResult(token.Value);
            })
            .Build();
    }
}
Run Code Online (Sandbox Code Playgroud)

更新 2:我在这里尝试了提示:https : //github.com/dotnet/aspnetcore/issues/18697

并将我的代码更改为:

        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chatHub?access_token=" + token.Value))
            .Build();
Run Code Online (Sandbox Code Playgroud)

但是没有快乐。

小智 1

这是我的解决方案并且有效

[Inject] HttpClient httpClient { get; set; }
[Inject] IAccessTokenProvider tokenProvider { get; set; }
HubConnection hubConnection { get; set; }

(...)

private async Task ConnectToNotificationHub()
{
    string url = httpClient.BaseAddress.ToString() + "notificationhub";

    var tokenResult = await tokenProvider.RequestAccessToken();

    if (tokenResult.TryGetToken(out var token))
    {
        hubConnection = new HubConnectionBuilder().WithUrl(url, options =>
        {
            options.Headers.Add("Authorization", $"Bearer {token.Value}");
        }).Build();


        await hubConnection.StartAsync();

        hubConnection.Closed += async (s) =>
        {
            await hubConnection.StartAsync();
        };

        hubConnection.On<string>("notification", m =>
        {
            string msg = m;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)