使用JWT

时间:2018-01-24 18:50:29

标签: angular .net-core signalr asp.net-identity

我正在使用

构建应用程序

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);

任何帮助都将非常感谢! 被困了几天,这是真正让这些东西一起工作的最后一块。

1 个答案:

答案 0 :(得分:2)

我看到你正在使用1.0.0-alpha2。不幸的是,1.0.0-alpha2中的TypeScript客户端没有JWT支持。要使用JWT,您需要使用即将发布的preview1客户端的每晚构建。有关详细信息,请参阅https://github.com/aspnet/SignalR#packages