Сбой аутентификации JWT с SignalR - PullRequest
0 голосов
/ 13 октября 2018

У меня есть REST API (ядро 2.1), который должен поддерживать SPA, предоставляя спокойные конечные точки и некоторые интерактивные функции в реальном времени с использованием SignalR;

Маршруты Hub / MVC выполняются на том же сервере, которыйтакже является поставщиком токена JWT.

После входа в систему клиентская сторона получает токен JWT, который помещается в заголовок для каждого запроса REST, в противном случае он получает 401 (это работает с атрибутом [Authorize]).

На стороне клиента приведенный ниже код пытается подключиться к моей конечной точке / концентратору: new HubConnectionBuilder().withUrl(HUB_URL, { accessTokenFactory: () => this.getToken() })
И если я помещу [Authorize] в свой класс-концентратор, я получаю следующую ошибку (без авторизации клиентможет отправлять и прослушивать правильно):

Соединение WebSocket с 'wss: // localhost: 5001 / hub? id = MY_ID & access_token = MY_TOKEN' не удалось: ошибка аутентификации HTTP;допустимые учетные данные недоступны

Сервер зарегистрировал неудачные проверки подлинности:

(Запустил console.log в AddJwtBearerOptions.Events.OnMessageReceived)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost [1]
Запрос на запуск HTTP / 1.1 GET https://localhost:5001/hub? id = MY_ID & access_token = MY_TOKEN
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2]
Авторизация не удалась.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler [12]
AuthenticationScheme: вызов на предъявителя.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost [2]
Запрос завершен в 0.3658ms401

В отличие от этих запросов, при использовании ЖЕ ЖЕВЫХ ЖЕТОК с запросами REST (при использовании [Authorize]) с Header: Bearer XXXX вместо строки запроса запускается OnTokenValidated.OnAuthenticationFailed никогда не запускается, даже если проверка подлинности завершается неудачно:

(Запускает файл console.log в AddJwtBearerOptions.Events.OnMessageReceived)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Запрос на запуск HTTP / 1.1 GET https://localhost:5001/api/products application / json
(Запускает файл console.log в AddJwtBearerOptions.Events.OnTokenValidated)
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler [2]
Успешно проверил токен.


Проверьте ниже моего ´Startup.cs`

ConfigureServices(IServiceCollection)

services.AddSignalR();
services.AddCors(option => option.AddPolicy("CorsPolicy", p => p.AllowAnyHeader().AllowAnyOrigin().AllowAnyMethod().AllowCredentials()));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
    options.TokenValidationParameters = new TokenValidationParameters{
        ValidateIssuer = true,
        ValidIssuer = Configuration["JWT:Issuer"],
        ValidateLifetime = true,
        ValidateAudience = false,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:SecurityKey"]))
    };
});

Configure(IApplicationBuilder)

app.UseAuthentication();
app.UseCors("CorsPolicy");
app.UseHttpsRedirection();
app.UseMvc();
app.UseSignalR(routes => {
     routes.MapHub<ApplicationHub>("/hub");
});

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2] Авторизация не удалась.информация: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler [12] Схема проверки подлинности: вызов был предъявлен.информация: Microsoft.AspNetCore.Hosting.Internal.WebHost [2] Запрос завершен за 0,3658 мс 401

Потратьте 20 часов на исправление.:( Причина была в:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class ChatHub : Hub<IChatClient>

Конфигурация моей службы:

services.AddAuthentication(options =>
{
     options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
     options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => ...)

UPD: полный пример работы с клиентом JS здесь .

0 голосов
/ 15 октября 2018

Вам также необходимо добавить этот блок в раздел .AddJwtBearer:

// We have to hook the OnMessageReceived event in order to
// allow the JWT authentication handler to read the access
// token from the query string when a WebSocket or 
// Server-Sent Events request comes in.
options.Events = new JwtBearerEvents
{
    OnMessageReceived = context =>
    {
        var accessToken = context.Request.Query["access_token"];

        // If the request is for our hub...
        var path = context.HttpContext.Request.Path;
        if (!string.IsNullOrEmpty(accessToken) &&
            (path.StartsWithSegments("/hub")))
        {
            // Read the token out of the query string
            context.Token = accessToken;
        }
        return Task.CompletedTask;
    }
};

Это можно найти здесь в документах .

...