【发布时间】:2023-01-14 18:06:47
【问题描述】:
在客户端使用 jwt 令牌成功登录后,我正在使用 SignalR 和 angular 在客户端之间创建聊天。一旦我添加了 -
[Authorize]
到我的集线器,我在尝试连接到 SignalR 时遇到此错误 -
调试:HubConnection 未能成功启动,因为错误“错误:无法完成与服务器的协商:错误::状态代码‘401’”。
在添加此属性之前,我的应用已成功连接到 SignalR,因此我知道问题出在授权上。我究竟做错了什么?
用户中心-
[Authorize] public class UserHub : Hub程序.cs-
var builder = WebApplication.CreateBuilder(args); builder.Services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder .WithOrigins("http://localhost:4200") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() .SetIsOriginAllowed((host) => true)); }); builder.Services.AddDbContext<TalkBackDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("TalkBackConnectionString"))); builder.Services.AddScoped<IContactRepository, ContactsRepository>(); builder.Services.AddScoped<IWebAPIService, WebAPIService>(); builder.Services.AddScoped<ISignalrService, SignalrService>(); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddSignalR(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = false, ValidateAudience = false, ValidAudience = builder.Configuration["Jwt:Audience"], ValidIssuer = builder.Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; options.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/user"))) { context.Token = accessToken; } return Task.CompletedTask; } }; });客户-
public startSignalrConnection(connectionUrl: any) { return new Promise<any>((resolve, reject) => { this.hubConnection = new HubConnectionBuilder() .withUrl(connectionUrl, { withCredentials: false, accessTokenFactory: () => localStorage.getItem('jwt')!, }) .configureLogging(LogLevel.Debug) .build();
【问题讨论】:
-
在客户端代码中,您尝试在创建集线器连接时通过选项对象中的 accessTokenFactory 属性将 JWT 令牌传递给集线器连接。但是您没有传递 credentials 属性设置为 true 的令牌。在客户端创建集线器连接时,尝试将
{ withCredentials: true, accessTokenFactory: () => localStorage.getItem('jwt')! }添加到选项对象。这将以“Authorization: Bearer {token}”格式在请求标头中发送 JWT 令牌,服务器将能够读取令牌并授权连接。 -
我已将其更改为“真”,但仍然出现相同的错误:“建立信号器连接时出错:错误:无法完成与服务器的协商:错误::状态代码为‘401’”。有任何想法吗?
-
您在哪里将任何类型的身份验证信息添加到您的 http 调用中?像 auth 拦截器或类似的。
-
如果我没理解错的话,我在网上看到
accessTokenFactory: () => localStorage.getItem('jwt')!应该就足够了 -
您是否将任何类型的 jwt 信息保存到本地存储中?
标签: asp.net angular authentication jwt signalr