我正在建立通知系统,但我遇到了一个问题,这导致我已经损失了几个小时。我的 jwt auth 与前端完美配合,但是当将(完全相同的)jwt 令牌发送到后端时,我从来无法访问 Context / Context.User 等。我的意思是,我获得了访问权限,但基本上是 User一切都是空的。
我尝试了 [AllowAnonymous] [Authorize] 的每种组合,使用方案授权,不使用方案授权,在整个集线器上授权,仅在 OnConnectedAsync 上授权等。
如果我像这样在 ConnectedAsync 内部手动解析令牌,一切正常:
var token = Context.GetHttpContext().Request.Query["access_token"];
var userIdString = GetUserIdFromToken(token);
public class TicketHub : Hub
{
private readonly ITicketsRepository _ticketRepository;
public TicketHub(ITicketsRepository ticketRepository)
{
_ticketRepository = ticketRepository;
}
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = "IsAuthenticated")]
public override async Task OnConnectedAsync()
{
var test = Context.User.Identity.IsAuthenticated;
var test2 = Context; // ->>>> NO CONTEXT HERE
我的program.cs:(大部分被跳过,仅包括中间件的顺序和身份验证模式)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(jwt =>
{
var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:Secret"]);
jwt.SaveToken = true;
jwt.TokenValidationParameters = tokenValidationParams;
jwt.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
path.StartsWithSegments("/TicketSocket"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
}
);
builder.Services.AddSignalR();
var app = builder.Build();
app.UseRouting();
app.UseWebSockets();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<TicketHub>("/TicketSocket");
}
我的前端:
this.connection = new HubConnectionBuilder()
.withUrl(`api/TicketSocket`, {
accessTokenFactory: () => this.$auth.strategy.token.get(),
})
.withAutomaticReconnect()
.build()
将Authorize属性放在OnConnectedAsync上是无效的。您需要将其放在 TicketHub 上。