我正在使用构建应用程序
角度 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。