2016-09-30 1 views
1

Я извлекая SID в моем контроллере WebAPI с помощьюВызов конкретной SID пользователя с помощью SignalR + Azure Mobile App аутентификации

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; 
    } 

И я получаю ненулевое значение. Однако, когда я пытаюсь называть конкретных клиентов-концентраторов, используя

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

ожидаемые клиенты не отвечают. На самом деле клиенты не реагируют. С учетом этого

 hubContext.Clients.All.refresh() 

действительно звонит всем. Я ничего не сделал

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

Но я думаю, что это должно быть право по умолчанию? Что мне не хватает? Возможно, есть какой-то способ проверить, что userIds находятся в Клиентах?

Обновление. Я нашел это Context.User.Identity.Name is null with SignalR 2.X.X. How to fix it?, который говорит о наличии signalr перед webapi, который я попытался безрезультатно. Я использую аутентификацию от 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 не может правильно получить пользователь.

Update 2. Может быть, мне нужно создать UseOAuthBearerAuthentication, который читает [х-Zumo-AUTH]

Update 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 

Не уверен, что это поможет, но сид от We bApi выглядят как sid:8ba1a8532eaa6eda6758c3e522f77c24

Обновление 4. Я нашел сид! Я изменил код своего концентратора на

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

и я получил сид. Не знаете, как Context.User.Identity.Name отличается от этого, но это действительно работает. Теперь вопрос, как я могу использовать данный SID для вызова

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

если я знаю NameIdentifier пользователя?

ответ

1

Особая благодарность @davidfowler за необычайно раздражающую и все же проницательную «почему это не было бы: smile:». Как только я наконец принял это Context.User.Identity.Имя всегда будет пустым, я был в состоянии получить хаб для получения SID с помощью

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

который привел меня посмотреть через код signalr для Пользователь.Идентичность.Имя в конечном итоге посадка на PrincipalUserIdProvider. Сюрприз, удивление, он назначает GetUserId на основе User.Identity.Name. Я создал новый 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(). Надеюсь, это поможет кому-то там.

 Смежные вопросы

  • Нет связанных вопросов^_^