使用 JWT 对 SignalR Hub 进行身份验证



我正在使用构建应用程序

角度 4

AspNetCore 2

AspNetCore.SignalR 1.0.0-alpha2-final

和 JWT 身份验证

我的问题是这个。我似乎无法在中心级别对用户进行身份验证

我有一个适用于所有控制器的"要求声明"策略

services.AddAuthorization(options =>
{
options.AddPolicy("ApiUser", policy => 
policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, 
Constants.Strings.JwtClaims.ApiAccess));
});

在控制器中,我做了

[Authorize(Policy = "ApiUser")]

然而,正如你们中的许多人可能知道的那样,您不允许从JavaScript向WebSockets添加授权标头,因此才华横溢的贡献者提供的解决方案 https://github.com/aspnet/SignalR 是将 JWT 令牌作为查询字符串传递。

然而,这让我有点难以理解。 这是我在启动时的身份验证配置.cs

services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = 
jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = 
jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new 
SigningCredentials(_signingKey, 
SecurityAlgorithms.HmacSha256);
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = 
jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = 
jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = 
JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = 
JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = 
jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
configureOptions.TokenValidationParameters = 
tokenValidationParameters;
configureOptions.SaveToken = true;

configureOptions.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var signalRTokenHeader = 
context.Request.Query["signalRTokenHeader"];
if (!string.IsNullOrEmpty(signalRTokenHeader) &&
(context.HttpContext.WebSockets.IsWebSocketRequest ||                                        
context.Request.Headers["Accept"] == "text/event-stream"))
{
context.Token = 
context.Request.Query["signalRTokenHeader"];
}
return Task.CompletedTask;
}
};
});

现在这里是客户端代码(打字稿)

ngOnInit() {
let authToken = localStorage.getItem('auth_token');
this.options = {
transport: TransportType.WebSockets,
authToken: authToken
};
this._hubConnection = new HubConnection('http://localhost:51143/chat', 
this.options);
this._hubConnection
.start()
.then(() => console.log('Connection started!'))            
.catch(err => console.log('Error while establishing connection :('));

这里的目标是像这样将我的身份验证令牌传递给 signalR 集线器(与我在 api 控制器上所做的方式相同,效果很好)

[Authorize(Policy = "ApiUser")]
public class ChatHub : HubWithPresence

以便我能够在集线器连接上下文中水化User.Identity

Clients.All.InvokeAsync("sendToAll", Context.User.Identity.Name, 
receivedMessage);

这里的任何帮助将不胜感激! 被困了几天,这是真正让这些东西协同工作的最后一块缺失部分。

我看到你使用的是 1.0.0-alpha2。不幸的是,在 1.0.0-alpha2 中的 TypeScript 客户端中没有 JWT 支持。若要使用 JWT,需要使用即将推出的预览版 1 客户端的夜间版本。有关更多详细信息,请参阅 https://github.com/aspnet/SignalR#packages。

相关内容

  • 没有找到相关文章

最新更新