2014-02-25 59 views
31

这让我疯狂。Context.User.Identity.Name在SignalR 2.X.X中为null。如何解决它?

我正在使用最新的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模板。

你知道什么是错的吗?

+0

好像连这么一个棘手的问题... SignalR所有者在哪里..我一直在阅读2.0.3版本,可能会在OnDisconnected时解决类似问题,但是很长一段时间没有消息。一些对安全工作至关重要的东西无法正常工作。不好运气。 – MRFerocius

+0

由于某些原因,如果计算机时钟不在正确的时间(例如一个月后),Context.User将为空。 –

回答

82

我找到最终的解决方案,这是我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什么之后,瞧!现在,它的workign预期。

 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

不错的答案:)。 Thx –

+2

谢谢!这让我挠了我的头... – joshb

+0

我很高兴这有助于你@joshb。这让我发疯:D – MRFerocius

4

如果您在使用网络API和SignalR在同一个项目,你必须映射SignalR 之前注册Web Api。

更改此:

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

要这样:

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

这是一年半提供的答案.- – MRFerocius

+5

@MRFerocius您提供的答案类似但不同。你的答案是在认证下移动app.MapSignalR()。我的**将移动** ** app.UseWebApi()'。有人使用Web Api和SignalR可能会发现这些信息很有用,因为它并不直观。 –

+1

这是为我做的!谢谢! – Slick86

0

如果您绘制/signalr作为 '支管线' 你需要做的是这样的。确保使用map.UseCookieAuthentication而不是app

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

提示:更改路径的外壳,让你可以验证它工作在URL栏。例如:当我看到youRaccount我知道它的工作:-)

1

只是确保auth。配置称为befor开始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(); 


    } 
} 

拥抱..

+0

确实!这个对我有用 – Andrii