У меня есть две службы aspnet.core. Один для IdentityServer 4 и один для API, используемого клиентами Angular4 +. Хаб SignalR работает на API. Все решение работает на докере, но это не имеет значения (см. Ниже).
Я использую неявный поток аутентификации, который работает безупречно. Приложение NG перенаправляет на страницу входа в IdentityServer, где пользователь входит в систему. После этого браузер перенаправляется обратно в приложение NG с токеном доступа. Затем токен используется для вызова API и установления связи с SignalR. Думаю, я прочитал все, что доступно (см. Источники ниже).
Поскольку SignalR использует веб-сокеты, которые не поддерживают заголовки, токен следует отправлять в строке запроса. Затем на стороне API токен извлекается и устанавливается для запроса так же, как и в заголовке. Затем токен проверяется, и пользователь авторизуется.
API работает без проблем, пользователи авторизуются, а заявки могут быть получены на стороне API. Так что проблем с IdentityServer быть не должно, поскольку SignalR не требует специальной настройки. Я прав?
Когда я не использую атрибут [Authorized] в концентраторе SignalR, рукопожатие успешно. Вот почему я думаю, что в используемой мной инфраструктуре докеров и обратном прокси-сервере нет ничего плохого (прокси настроен на включение веб-сокетов).
Итак, без авторизации SignalR работает. При авторизации клиент NG во время рукопожатия получает следующий ответ:
Failed to load resource: the server responded with a status of 401
Error: Failed to complete negotiation with the server: Error
Error: Failed to start the connection: Error
Запрос
Request URL: https://publicapi.localhost/context/negotiate?signalr_token=eyJhbGciOiJSUz... (token is truncated for simplicity)
Request Method: POST
Status Code: 401
Remote Address: 127.0.0.1:443
Referrer Policy: no-referrer-when-downgrade
В ответ я получаю:
access-control-allow-credentials: true
access-control-allow-origin: http://localhost:4200
content-length: 0
date: Fri, 01 Jun 2018 09:00:41 GMT
server: nginx/1.13.10
status: 401
vary: Origin
www-authenticate: Bearer
Согласно журналам, токен успешно проверен. Я могу включить полные журналы, но подозреваю, в чем проблема. Я включу эту часть сюда:
[09:00:41:0561 Debug] Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler AuthenticationScheme: Identity.Application was not authenticated.
[09:00:41:0564 Debug] Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler AuthenticationScheme: Identity.Application was not authenticated.
Я получаю их в файле журнала и не понимаю, что это значит. Я включаю часть кода в API, где я получаю и извлекаю токен вместе с конфигурацией аутентификации.
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddIdentityServerAuthentication(options =>
{
options.Authority = "http://identitysrv";
options.RequireHttpsMetadata = false;
options.ApiName = "publicAPI";
options.JwtBearerEvents.OnMessageReceived = context =>
{
if (context.Request.Query.TryGetValue("signalr_token", out StringValues token))
{
context.Options.Authority = "http://identitysrv";
context.Options.Audience = "publicAPI";
context.Token = token;
context.Options.Validate();
}
return Task.CompletedTask;
};
});
Других ошибок, исключений в системе нет. Я могу отладить приложение, и вроде все в порядке.
Что означают включенные строки журнала? Как я могу отладить происходящее во время авторизации?
РЕДАКТИРОВАТЬ: Я почти забыл упомянуть, что я думал, что проблема связана со схемами аутентификации, поэтому я установил для каждой схемы ту, которая, по моему мнению, была необходима. Однако, к сожалению, это не помогло.
Я здесь немного невежественен, поэтому ценю любое предложение. Спасибо.
Источники информации:
Передать токен аутентификации в SignalR
Защита SignalR с помощью IdentityServer
Microsoft docs по авторизации SignalR