我正在使用
构建应用程序Angular 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标记作为查询字符串传递。
然而,这有点让我不知所措。这是我在startup.cs中的auth配置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;
}
};
});
现在这里是客户端代码(typescript)
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 :('));
这里的目标是将我的authtoken传递给signalR集线器(就像我在我的api控制器上做的那样,效果很好)
[Authorize(Policy = "ApiUser")]
public class ChatHub : HubWithPresence
这样我就可以在HubConnection上下文中保留User.Identity
Clients.All.InvokeAsync("sendToAll", Context.User.Identity.Name,
receivedMessage);
任何帮助都将非常感谢! 被困了几天,这是真正让这些东西一起工作的最后一块。
答案 0 :(得分:2)
我看到你正在使用1.0.0-alpha2。不幸的是,1.0.0-alpha2中的TypeScript客户端没有JWT支持。要使用JWT,您需要使用即将发布的preview1客户端的每晚构建。有关详细信息,请参阅https://github.com/aspnet/SignalR#packages。