c# - 具有标识的 Blazor WebAssembly 的 SignalR Hub 授权

标签 c# asp.net-core signalr blazor

我已经使用 JWT 身份验证设置了 SignalR Blazor WebAssembly 应用程序,配置为通过查询字段 access_token 发送 token 。
在服务器上,我看到它正在从此值分配 context.Token。
但是,对于使用 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 注释的集线器,我得到 401。
为什么不授权?
这是集线器的代码:https://github.com/jonasarcangel/SignalRAuthTest/blob/master/SignalRAuthTest/Server/SignalR/MessagesHub.cs
这是我在 Startup.cs 中的内容:https://github.com/jonasarcangel/SignalRAuthTest/blob/master/SignalRAuthTest/Server/Startup.cs
这是客户端:
https://github.com/jonasarcangel/SignalRAuthTest/blob/master/SignalRAuthTest/Client/Pages/SignalR.razor.cs

最佳答案

这适用于 WebAssembly 自托管身份服务器,在集线器上具有 [Authorize] 属性(使用不记名 token ......)。
重要的是配置一个函数来在集线器启动时获取 token 。集线器连接可以使用它需要的任何传输机制来发送访问 token 。

 hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"), options =>
            {
                options.AccessTokenProvider = async () =>
                {
                    var accessTokenResult = await AccessTokenProvider.RequestAccessToken();
                    accessTokenResult.TryGetToken(out var accessToken);
                    return accessToken.Value;
                };
            })
            .Build();
我改编自 3.1 SignalR 教程的完整页面。
@using Microsoft.AspNetCore.SignalR.Client
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Microsoft.AspNetCore.Authorization

@page "/chat"
@attribute [Authorize]
@implements IDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    [Inject]
    public NavigationManager NavigationManager { get; set; }

    [Inject]
    public IAccessTokenProvider AccessTokenProvider { get; set; }

    protected override async Task OnInitializedAsync()
    {

        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"), options =>
            {
                options.AccessTokenProvider = async () =>
                {
                    var accessTokenResult = await AccessTokenProvider.RequestAccessToken();
                    accessTokenResult.TryGetToken(out var accessToken);
                    return accessToken.Value;
                };
            })
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    Task Send() =>
        hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public void Dispose()
    {
        _ = hubConnection.DisposeAsync();
    }
}
这是一个工作 repo
这是我使用 Identity 项目为标准 WebAssembly 制作的 changes。除了我发布的页面之外,我基本上遵循了 WebAssembly Signalr tutorial
在您的解决方案中:
SignalR.razor
 hubConnection = new HubConnectionBuilder()
             .WithUrl(NavigationManager.ToAbsoluteUri("/messageshub"), options =>
             {
                 options.AccessTokenProvider = async () =>
                 {
                     var accessTokenResult = await tokenProvider.RequestAccessToken();
                     accessTokenResult.TryGetToken(out var accessToken);
                     return accessToken.Value;
                 };
             })
            .Build();
在 Startup.cs 中,将此更改回模板。
services.AddAuthentication()
                  .AddIdentityServerJwt();
然后只需在您的集线器上[授权]。
您的代码 working

关于c# - 具有标识的 Blazor WebAssembly 的 SignalR Hub 授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63083267/

相关文章:

javascript - 如何从 ASP.NET 委托(delegate)执行 Response.Redirect

c# - 如何将图像保存为位图图像文件?

c# - 使多个控件使用相同的工具提示消息(c# 客户端应用程序)

c# - 可以使用相关实体(而不是相关 ID)使用 OData 创建实体吗?

asp.net-core - 在 Visual Studio Team Services 托管代理上构建的 ASP.Net Core 1.0 项目上未发现使用 xUnit 的测试

c# - 使用 SignalR 和 IProgress 接口(interface)的进度报告

javascript - SignalR 集线器 : JavaScript runtime error: Unable to get property 'multipleFileHub' of undefined or null reference

c# - 备份和恢复 SQLCE .sdf 数据库

asp.net-core - project.json 版本控制格式

asp.net-core - Entity Framework 核心中的元数据工作空间在哪里?