web-dev-qa-db-fra.com

Context.User.Identity.Name est null avec SignalR 2.X.X. Comment le réparer?

Cela me rend fou.

J'utilise la dernière version de signalR (2.0.2). Ceci est mon code hub (OnConnected)

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

Et voici la méthode de connexion de mon contrôleur:

        [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");
        }

J'ai trouvé que certaines personnes ont ce problème sur OnDisconnected, je n'y arrive même pas.

J'utilise le modèle MCV5.

Avez-vous une idée de ce qui ne va pas?

39
MRFerocius

J'ai trouvé la solution finale, voici le code de ma classe de démarrage 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());    
    }

Je me suis fait du café, je me suis dit "Qu'en est-il du mappage de SignalR APRÈS l'authentification, et le tour est joué! Maintenant, ça marche comme prévu.

        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();    
    }
94
MRFerocius

Si vous utilisez Web Api et SignalR dans le même projet, vous devez mapper SignalR avant en enregistrant Web Api.

Change ça:

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

Pour ça:

app.MapSignalR();
app.UseWebApi(GlobalConfiguration.Configuration);
5
Josh Noe

Si vous mappez /signalr en tant que "pipeline ramifié", vous devez le faire. Assurez-vous d'utiliser bp.UseCookieAuthentication et non app:

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

Astuce: j'ai changé le boîtier de manière généreuse, donc quand je vois youRaccount dans la barre d'URL, je sais que cela a fonctionné :-)

2
Simon_Weaver

assurez-vous juste d'auth. la configuration est appelée avant de démarrer app.MapSignalR ()

j'ai changé ça

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



    }
}

pour ça

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


    }
}

câlins ..

2
islam khateeb

.NET Core SignalR uniquement

Pour le .NET Core SignalR plus récent, les instructions complètes expliquent que lorsque vous utilisez des websockets, vous devez retirer manuellement le accessToken de la chaîne de requête. C'est facile à manquer.

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

Fondamentalement, lorsque vous appelez AddAuthentication(), vous devez ajouter AddJwtBearer() puis définir un gestionnaire pour le gestionnaire OnMessageReceived.

Recherchez "OnMessageReceived" dans le lien ci-dessus pour le code. C'est un peu noueux dans le sens où vous devez même l'ajouter vous-même - mais c'est pourquoi il est facile de le manquer aussi.

0
Simon_Weaver