Context.User.Identity.Name is null with SignalR 2.X.X. How to fix it?
This is driving me insane.
I'm using latest signalR release (2.0.2). This is my hub code (OnConnected)
public override Task OnConnected()
{
//User is null then Identity and Name too.
Connections.Add(Context.User.Identity.Name, Context.ConnectionId);
return base.OnConnected();
}
And this is my Controller's login method:
[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");
}
I found that some people are having this issue on OnDisconnected, I don't even make it there.
I'm using MCV5 template.
Do you have any idea what is wrong?
I found the final solution, this is the code of my OWIN startup class:
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());
}
Making myself some coffee, I thought "What about mapping SignalR AFTER the authentication, and voila! Now it's workign as expected.
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();
}
If you're using Web Api and SignalR in the same project, you have to map SignalR before registering Web Api.
Change this:
app.UseWebApi(GlobalConfiguration.Configuration);
app.MapSignalR();
To this:
app.MapSignalR();
app.UseWebApi(GlobalConfiguration.Configuration);