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.
Есть ли у вас какие-либо идеи, что не так?
Ответы
Ответ 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" в приведенной выше ссылке для кода. Это немного грубовато в том смысле, что вам даже нужно добавить это самостоятельно - но поэтому его тоже легко пропустить.