在与Blazor WASM的信号机连接期间使用JWT
我搞砸了Blazor+信号机的连接。我想使用JWT授权呼叫信号员 基本上,我想附加到信号机呼叫JWT 这是我的Blazor WASM信号机代码在与Blazor WASM的信号机连接期间使用JWT,jwt,signalr,blazor,blazor-client-side,Jwt,Signalr,Blazor,Blazor Client Side,我搞砸了Blazor+信号机的连接。我想使用JWT授权呼叫信号员 基本上,我想附加到信号机呼叫JWT 这是我的Blazor WASM信号机代码 @page "/" @using Microsoft.AspNetCore.SignalR.Client @inject NavigationManager NavigationManager @implements IDisposable <div class="form-group"> <label>
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@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;
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
.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();
}
}
布拉佐是怎么做的
我试过这个:
var token = "eyJhb(...)";
hubConnection = new HubConnectionBuilder()
.WithUrl($"{Configuration["Url"]}/chathub", (HttpConnectionOptions x) =>
{
x.Headers.Add("Authorization", $"Bearer: {token}");
})
.Build();
但它抛出了一个错误:
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: The format of value 'Bearer: eyJh' is invalid.
System.FormatException: The format of value 'Bearer: eyJhbG' is invalid.
解决办法是。。。阅读文档
var token = "eyJ";
hubConnection = new HubConnectionBuilder()
.WithUrl($"{Configuration["Url"]}/chathub?access_token={token}")
.Build();
令牌通过url在连接建立时提供
我们需要修改startup.cs以支持OnMessageReceived
文档url:
@HenkHolterman这会很奇怪,因为我正在使用
内的令牌
来ping一个具有Authorize
属性的端点,它工作正常,同时如果没有这个令牌,我将收到未经授权的
。我也在jwt.io
上试用过,它说签名已验证
(好)所以看起来令牌是OK的。您应该在客户端上仍然使用accessTokenFactory
,这比在url中放入查询字符串要干净得多。另外,如果可能的话,它将使用标题而不是查询字符串。@Brennan你能给我举个例子吗?我找不到那个类你在你的原始问题.withUrl(“/hubs/chat”,{accessTokenFactory:()=>this.loginToken})中用过它@Brennan这是javascript文档中的例子,但我在C中找不到那个类#
var token = "eyJ";
hubConnection = new HubConnectionBuilder()
.WithUrl($"{Configuration["Url"]}/chathub?access_token={token}")
.Build();
services.AddAuthentication(options =>
{
// Identity made Cookie authentication the default.
// However, we want JWT Bearer Auth to be the default.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
// Configure the Authority to the expected value for your authentication provider
// This ensures the token is appropriately validated
options.Authority = /* TODO: Insert Authority URL here */;
// We have to hook the OnMessageReceived event in order to
// allow the JWT authentication handler to read the access
// token from the query string when a WebSocket or
// Server-Sent Events request comes in.
// Sending the access token in the query string is required due to
// a limitation in Browser APIs. We restrict it to only calls to the
// SignalR hub in this code.
// See https://docs.microsoft.com/aspnet/core/signalr/security#access-token-logging
// for more information about security considerations when using
// the query string to transmit the access token.
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
// If the request is for our hub...
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/hubs/chat")))
{
// Read the token out of the query string
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});