Подтвердить что ты не робот

Context.User.Identity.Name имеет значение null с SignalR 2.X.X. Как это исправить?

Это сводит меня с ума.

Я использую последнюю версию signalR (2.0.2). Это мой код хаба (OnConnected)

        public override Task OnConnected()
        {
            //User is null then Identity and Name too.
            Connections.Add(Context.User.Identity.Name, Context.ConnectionId);
            return base.OnConnected();
        }

И это мой метод входа в контроллер:

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
              var user = await UnitOfWork.UserRepository.FindAsync(model.UserName,  model.Password);

                if (user != null)
                {
                    await SignInAsync(user, model.RememberMe);

                    return RedirectToLocal(returnUrl);
                }
            }

            TempData["ErrorMessage"] = Resources.InvalidUserNameOrPassword;

            // If we got this far, something failed, redisplay form
            return RedirectToAction("Index","Home");
        }

Я обнаружил, что некоторые люди сталкиваются с этой проблемой в OnDisconnected, я даже не делаю этого.

Я использую шаблон MCV5.

Есть ли у вас какие-либо идеи, что не так?

4b9b3361

Ответ 1

Я нашел окончательное решение, это код моего стартового класса OWIN:

        public void Configuration(IAppBuilder app)
        {
        app.MapSignalR();

        // Enable the application to use a cookie to store information for the signed i user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Home/Index")
        });

        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        app.UseMicrosoftAccountAuthentication(new MicrosoftProvider().GetAuthenticationOptions());
        app.UseTwitterAuthentication(new TwitterProvider().GetAuthenticationOptions());
        app.UseFacebookAuthentication(new FacebookProvider().GetAuthenticationOptions());
        app.UseGoogleAuthentication(new GoogleProvider().GetAuthenticationOptions());    
    }

Сделав себе кофе, я подумал "Как насчет отображения SignalR ПОСЛЕ аутентификации и voila! Теперь он работает как ожидалось.

        public void Configuration(IAppBuilder app)
        {
        // Enable the application to use a cookie to store information for the signed i user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Home/Index")
        });

        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        app.UseMicrosoftAccountAuthentication(new MicrosoftProvider().GetAuthenticationOptions());
        app.UseTwitterAuthentication(new TwitterProvider().GetAuthenticationOptions());
        app.UseFacebookAuthentication(new FacebookProvider().GetAuthenticationOptions());
        app.UseGoogleAuthentication(new GoogleProvider().GetAuthenticationOptions());

        app.MapSignalR();    
    }

Ответ 2

Если вы используете Web Api и SignalR в том же проекте, вам нужно сопоставить SignalR перед регистрацией Web Api.

Измените это:

app.UseWebApi(GlobalConfiguration.Configuration);
app.MapSignalR();

Для этого:

app.MapSignalR();
app.UseWebApi(GlobalConfiguration.Configuration);

Ответ 3

Если вы отображаете /signalr как "разветвленный конвейер", вам нужно это сделать. Убедитесь, что вы используете bp.UseCookieAuthentication а не app:

app.Map("/signalr", bp =>
{
   bp.UseCookieAuthentication(new CookieAuthenticationOptions
   {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/store/youRaccount/login")
   });

Совет: я преднамеренно изменил корпус, поэтому, когда я вижу youRaccount в строке URL, я знаю, что это сработало :-)

Ответ 4

просто убедитесь, что auth. конфигурация называется befor start app.MapMignalrR()

я изменил это

 public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
        ConfigureAuth(app);



    }
}

к этому

 public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
        app.MapSignalR();


    }
}

объятия..

Ответ 5

Только .NET Core SignalR

Для более нового .NET Core SignalR полные инструкции объясняют, что при использовании веб-сокетов вам необходимо вручную извлечь accessToken из строки запроса. Это легко пропустить.

https://docs.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-2.2

В основном, когда вы вызываете AddAuthentication() вам нужно добавить AddJwtBearer() а затем установить обработчик для обработчика OnMessageReceived.

Найдите "OnMessageReceived" в приведенной выше ссылке для кода. Это немного грубовато в том смысле, что вам даже нужно добавить это самостоятельно - но поэтому его тоже легко пропустить.