2016-09-30 67 views
1

我使用调用使用SignalR + Azure的移动应用认证

private string GetAzureSID() 
    { 
     var principal = this.User as ClaimsPrincipal; 
     var nameIdentifier = principal.FindFirst(ClaimTypes.NameIdentifier); 
     if (nameIdentifier != null) 
     { 
      var sid = nameIdentifier.Value; 
      return sid; 
     } 
     return null; 
    } 

检索SID在我的WebAPI控制器和我得到一个非空值特定用户的SID。但是,当我尝试呼叫使用的特定集线器客户端

  hubContext.Clients.User(sid).refresh() 

预期的客户端不响应。其实没有客户回应。这就是说

 hubContext.Clients.All.refresh() 

确实叫大家。我没有做过任何类似的事情

var idProvider = new PrincipalUserIdProvider(); 
GlobalHost.DependencyResolver.Register (typeof(IUserIdProvider),() => idProvider); 

但我认为应该是默认的权利?我错过了什么?也许有一些方法可以检查客户端中的用户ID?

更新。我发现这个Context.User.Identity.Name is null with SignalR 2.X.X. How to fix it?它讨论了之前webapi有signalr,我试图无济于事。尽管我使用Azure身份验证,但这可能是问题所在。这里是我的ConfigureMobileApp看起来像

public static void ConfigureMobileApp(IAppBuilder app) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 

     new MobileAppConfiguration() 
      .UseDefaultConfiguration() 
      .ApplyTo(config); 

     // Use Entity Framework Code First to create database tables based on your DbContext 
     //   Database.SetInitializer(new MobileServiceInitializer()); 
     var migrator = new DbMigrator(new Migrations.Configuration()); 
     migrator.Update(); 

     MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings(); 

     if (string.IsNullOrEmpty(settings.HostName)) 
     { 
      app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions 
      { 
       // This middleware is intended to be used locally for debugging. By default, HostName will 
       // only have a value when running in an App Service application. 
       SigningKey = ConfigurationManager.AppSettings["SigningKey"], 
       ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] }, 
       ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] }, 
       TokenHandler = config.GetAppServiceTokenHandler() 
      }); 
     } 

     app.MapSignalR(); 
     app.UseWebApi(config); 
    } 

这可能是因为该问题是认证后不知何故从Azure中来吗?我试图从我的客户

[Authorize] 
public class AppHub : Hub 
{ 
    public string Identify() 
    { 
     return Context.User.Identity.Name; 
    } 
} 

调用集线器但结果却是“空”,所以我觉得Signalr无法获得正确的用户。

更新2可能是我需要创建一个UseOAuthBearerAuthentication读取[X-谟-AUTH]

更新3我增加了一些更多的功能到我中心

public string Identify() 
    { 
     return HttpContext.Current.User.Identity.Name; 
    } 

    public bool Authenticated() 
    { 
     return Context.User.Identity.IsAuthenticated; 
    } 

    public string Bearer() 
    { 
     return Context.Headers["x-zumo-auth"]; 
    } 

结果是

null 
true 
the correct bearer token 

不知道这是否有帮助,但从我们的sid bApi看起来像sid:8ba1a8532eaa6eda6758c3e522f77c24

更新4.我找到了sid!我将我的中心代码更改为

public string Identify() 
    { 
     //   return HttpContext.Current.User.Identity.Name; 
     var identity = (ClaimsIdentity)Context.User.Identity; 
     var tmp = identity.FindFirst(ClaimTypes.NameIdentifier); 
     return tmp.Value; 
    } 

我得到了sid。不确定Context.User.Identity.Name如何与此不同,但这确实起作用。现在的问题是,我该如何使用给定的SID调用

hubContext.Clients.User(...???...).refresh()

,如果我知道用户的的NameIdentifier?

回答

1

特别感谢@davidfowler,因为它非常令人讨厌而又敏感的“为什么它不会为null:smile:”。一旦我最终接受了Context.User.Identity。名称将永远是空的,我能得到集线器使用检索SID

var identity = (ClaimsIdentity)Context.User.Identity; 
    var tmp = identity.FindFirst(ClaimTypes.NameIdentifier); 
    return tmp.Value; 

害得我通过了User.Identity.Name的signalr代码,最终降落在PrincipalUserIdProvider看。惊喜,惊喜,它基于User.Identity.Name分配GetUserId。我创建了一个新的IUserIdProvider:

public class ZumoUserIdProvider : IUserIdProvider 
{ 
    public string GetUserId(IRequest request) 
    { 
     if (request == null) 
     { 
      throw new ArgumentNullException("request"); 
     } 

     if (request.User != null && request.User.Identity != null) 
     { 
      var identity = (ClaimsIdentity)request.User.Identity; 
      var identifier = identity.FindFirst(ClaimTypes.NameIdentifier); 
      if (identifier != null) 
      { 
       return identifier.Value; 
      } 
     } 

     return null; 
    } 
} 

和Startup.cs

public void Configuration(IAppBuilder app) 
    { 
     var userIdProvider = new ZumoUserIdProvider(); 
     GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => userIdProvider); 

     ConfigureMobileApp(app); 
    } 

和像变魔术一样,我现在可以hubContext.Clients.User(SID).REFRESH()任何事情之前注册它。希望这可以帮助那里的人。

相关问题