授权不适用于Signalr连接

时间:2019-09-05 16:45:26

标签: c# wpf asp.net-web-api jwt signalr

JWTBearerToken授权在我的Signalr应用程序中不起作用。

作为服务器,我使用Asp.net core 2.2 WebAPI,作为客户端,我创建了WPF应用程序。

在客户端应用程序启动时,登录方法将称为:

  private async void Login()
        {
            var httpContent = new StringContent(JsonConvert.SerializeObject(currentUser), Encoding.UTF8, "application/json");
            var response = await new HttpClient().PostAsync("https://localhost:5001/api/auth/user", httpContent);

            if (response.IsSuccessStatusCode)
            {
                currentUser = JsonConvert.DeserializeObject<User>(await response.Content.ReadAsStringAsync());

                connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:5001/notify", options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult(currentUser.Token);
                })
                .Build();
            }
        }

用户类如下:

 public class User
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string Token { get; set; }
    }

因此,在我的情况下,响应对象包含服务器分配的令牌。

如果我现在单击“连接”按钮,则将调用以下方法:

 private async void connectButton_Click(object sender, RoutedEventArgs e)
        {
            #region snippet_ConnectionOn
            connection.On<string, string>("BroadcastMessage", (id, message) =>
            {
                this.Dispatcher.Invoke(() =>
                {
                    var newMessage = $"{id}: {message}";
                    messagesList.Items.Add(newMessage);
                });
            });
            #endregion

            try
            {
                await connection.StartAsync();
                messagesList.Items.Add("Connection started");
                connectButton.IsEnabled = false;
                sendButton.IsEnabled = true;
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.Message);
            }
        }

服务器对连接的响应。StartAsync()方法导致“未经授权”异常。

这是我的服务器启动类的样子:

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<ISitesRepository, SitesRepository>();
            services.AddSingleton<INotificationManager, NotificationManager>();
            services.AddSingleton<IUserIdProvider, NameUserIdProvider>();
            services.AddSignalR();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            var authSettingsSection = Configuration.GetSection("AuthSettings");
            services.Configure<AuthSettings>(authSettingsSection);


            var authSettings = authSettingsSection.Get<AuthSettings>();
            var key = Encoding.ASCII.GetBytes(authSettings.Secret);
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                //x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters =
               new TokenValidationParameters
               {
                   LifetimeValidator = (before, expires, token, param) =>
                   {
                       return expires > DateTime.UtcNow;
                   },
                   ValidateAudience = false,
                   ValidateIssuer = false,
                   ValidateActor = false,
                   ValidateLifetime = true,
                   IssuerSigningKey = new SymmetricSecurityKey(key)
               };
                x.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                   {
                       var accessToken = context.Request.Query["access_token"];

                       if (string.IsNullOrEmpty(accessToken) == false)
                       {
                           context.Token = accessToken;
                       }

                       var found = context.Request.Headers["Authorization"];

                       if (found != default(Microsoft.Extensions.Primitives.StringValues))
                       {
                           var foundToken = found.FirstOrDefault(h => h.StartsWith("Bearer"));
                           context.Token = foundToken.Replace("Bearer ", "");
                       }

                       return Task.CompletedTask;
                   }
                };

            });

            services.AddScoped<IAuthService, AuthService>();
        }

context.Request.Query [“ access_token”] 始终返回空值。

这是集线器的测试代码:

 [Authorize]
    public class NotifyHub: Hub, INotifyHub
    {

        public NotifyHub() { }

        //public override async Task OnConnectedAsync()
        //{
        //    await Groups.AddToGroupAsync(Context.ConnectionId, "Devices");
        //    await base.OnConnectedAsync();
        //}

        //public override async Task OnDisconnectedAsync(Exception exception)
        //{
        //    await Groups.RemoveFromGroupAsync(Context.ConnectionId, "Devices");
        //    await base.OnDisconnectedAsync(exception);
        //}

        public async Task ReceivedBroadcastMessage(string id, string message)
        {
            await Task.Run(() =>
            {
              if  (id == "a")
                {
                    SendBroadcastMessage("b", "c");
                }
            });
        }

        public async Task SendBroadcastMessage(string id, string message)
        {
            await Clients.All.SendAsync("BroadcastMessage", id, message);
        }
    }

有什么想法吗?

0 个答案:

没有答案