Аутентификация клиента консоли SignalR .NET Core 2.1 в веб-приложении, которое использует удостоверение в качестве пользовательского интерфейса.

Используя .NET Core 2.1 и VS2017 preview 2, я создал простой веб-сервер с «Identity as UI», как описано здесь, а затем добавил чат SignalR после это.

В частности, у меня есть:

app.UseAuthentication();
app.UseSignalR((options) => {
    options.MapHub<MyHub>("/hubs/myhub");
});

..

[Authorize]
public class MyHub : Hub

..

"iisSettings": {
  "windowsAuthentication": false,
  "anonymousAuthentication": true,
     "iisExpress": {
     "applicationUrl": "http://localhost:5000",
     "sslPort": 0

Я запускаю отладчик, который открывает браузер, регистрирую пользователя и вхожу в систему, затем перехожу к http://localhost:5000/SignalRtest (моя страница бритвы, которая использует signalr.js) и убедитесь, что чат работает нормально.

Теперь я пытаюсь создать клиент чата для консольного приложения .NET Core:

class Program
{
    public static async Task SetupSignalRHubAsync()
    {
        var hubConnection = new HubConnectionBuilder()
                    .WithUrl("http://localhost:5000/hubs/myhub")
                    .Build();

        await hubConnection.StartAsync();
        await hubConnection.SendAsync("Send", "consoleapp");
    }

    public static void Main(string[] args)
    {
        SetupSignalRHubAsync().Wait();
    }
}

Моя проблема в том, что я не знаю, как аутентифицировать этого клиента?

РЕДАКТИРОВАТЬ:

(из https://github.com/aspnet/SignalR/issues/2455)

"Причина, по которой он работает в браузере, заключается в том, что браузер имеет файл cookie с момента вашего входа в систему, поэтому он отправляет его автоматически, когда SignalR запрашивает его. Чтобы сделать что-то подобное в клиенте .NET, вам нужно будет вызвать REST API. на вашем сервере, который может установить файл cookie, извлечь файл cookie из HttpClient, а затем предоставить его при вызове .WithUrl, например:

var loginCookie = /* get the cookie */
var hubConnection = new HubConnectionBuilder()
    .WithUrl("http://localhost:5000/hubs/myhub", options => {
        options.Cookies.Add(loginCookie);
    })
    .Build();

Теперь я назначил награду за этот вопрос, надеясь получить решение, показывающее, как аутентифицировать клиент консоли .NET Core 2.1 SignalR с сервером SignalR веб-приложения .NET Core 2.1, который использует «Identity as UI». Мне нужно получить файл cookie с сервера, а затем добавить его в SignalR HubConnectionBuilder (у которого теперь есть метод WithCookie).

Обратите внимание, что я не ищу сторонние решения, такие как IdentityServer. Спасибо!


person kofifus    schedule 08.06.2018    source источник


Ответы (1)


В итоге я заставил это работать вот так:

На сервере я создал логин, а затем в Login.cshtml.cs добавил

[AllowAnonymous]
[IgnoreAntiforgeryToken(Order = 1001)]
public class LoginModel : PageModel

То есть мне не нужен токен защиты от подделки при входе в систему (что в любом случае не имеет смысла)

Тогда клиентский код выглядит следующим образом:

HttpClientHandler handler = new HttpClientHandler();
CookieContainer cookies = new CookieContainer();
handler.CookieContainer = cookies;
HttpClient client = new HttpClient(handler);

var uri = new Uri("http://localhost:5000/Identity/Account/Login");
string jsonInString = "Input.Email=myemail&Input.Password=mypassword&Input.RememberMe=false";
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(jsonInString, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded"));
var responseCookies = cookies.GetCookies(uri);
var authCookie = responseCookies[".AspNetCore.Identity.Application"];

var hubConnection = new HubConnectionBuilder()
        .WithUrl("http://localhost:5000/hubs/myhub", options =>
        {
            options.Cookies.Add(authCookie);
        })
        .Build();

await hubConnection.StartAsync();
await hubConnection.SendAsync("Send", "hello!");

(конечно, пароль будет в другом месте в развертывании)

person kofifus    schedule 08.06.2018
comment
Для всех, кто изучает это, хотя ответ @kofifus достаточно хорош, чтобы пометить его как правильный, вам, вероятно, следует избегать использования файлов cookie. Файлы cookie хороши для запросов API, но если вы работаете с SignalR и особенно с .NET SignalR Clients (или фактически с любыми другими клиентами, отличными от JS / браузера), вам следует изучить аутентификацию токена носителя - здесь - person eja; 04.06.2019
comment
@eja: Проблема в том, что аутентификация токена на предъявителя - это огромная настройка инфраструктуры по сравнению с простым входом в систему. - person Paulo Neves; 12.02.2020