Azure功能如何针对SignalR进行身份验证?

时间:2016-09-20 17:03:27

标签: azure authentication signalr azure-functions

我正在编写一个类似Web应用程序的仪表板。外部系统的状态变化应通过SignalR下推到浏览器。外部系统将其更新发送到Azure Service Bus主题。我编写了一个Azure功能,它将由其中一个主题触发。该功能通过SignalR .Net客户端库连接到SignalR集线器,并将消息转发到集线器。然后,集线器将消息发送给浏览器。

现在这个工作正常。下一步是启用SignalR集线器的身份验证。 Web应用程序的其他部分需要身份验证。用户使用其Azure AD凭据登录。

问题是Azure功能如何针对SignalR进行身份验证?在Azure功能应用程序的应用程序设置中保存一些凭据是不行的。

我研究了SignalR的扩展技术的解决方法。我们可以将服务总线主题配置为背板。每个SignalR集线器都会将消息的副本发送到主题中,以便集线器的其他实例获取消息并将其下推到其连接的客户端。想法是Azure功能将状态信息推送到背板主题。但遗憾的是SignalR使用未知编码。所以这种解决方法是不可能的。

@ astaykov的答案

  1. 在SignalR的应用注册中添加应用角色。

    "appRoles": [
      {
        "allowedMemberTypes": [
          "Application"
        ],
        "displayName": "Access SignalR Backend",
        "id": "239de039-e2c5-445c-8454-ccdc51888b94",
        "isEnabled": true,
        "description": "Allow the application to access SignalR Backend.",
        "value": "access"
      }
    ],
    
  2. 将Azure功能应用的应用注册与上述应用角色相关联。确保Azure功能应用程序的注册类型为Web app / API。
  3. 在Azure Function App的应用注册中创建一个密钥,并在获取令牌时使用它。

    var ctx = new AuthenticationContext(tenant);
    var cred = new ClientCredential(functionAppRegistrationId, key);
    AuthenticationResult result = await ctx.AcquireTokenAsync(signalRRegistrationId, cred);
    
  4. 在查询字符串中使用令牌。在互联网上搜索承载认证SignalR。

1 个答案:

答案 0 :(得分:6)

你提出两个问题。所以我会单独发痒。

  

问题是Azure功能如何进行身份验证   SignalR?在Azure的应用程序设置中保存一些凭据   功能应用是不行的。

正如@GreameMiller已经提到的那样,你应该看看使用OAuth Bearer Token验证SignalR。对于您的功能应用,您可以create a Service Principal in your Azure AD使用它来获取SignalR的有效令牌(必须是另一个Application in Azure AD,或与您的网络应用相同)。后者你可能已经完成了,你需要得到前者。

一个非常重要的事情 - 一旦在Azure AD中同时获得"applications" (Service Principals),就必须确保“功能应用服务主体”可以通过明确授予“SignalR Web App”来访问“SignalR Web App” Azure AD门户。再次从that article,您必须转到“功能应用程序”应用程序的配置设置,并确保配置“对其他应用程序的权限”。如果您已正确配置WebApp(使用SignalR),您将在可用的配置应用程序列表中看到该选项,只有选项 - 访问应用程序名称。您必须使用Application Permissions Delegated Permissions

其余的工作是标准的OAuth2客户端编程 - 客户端ID +客户端密钥。但是,是的,您必须将这些保留在功能应用程序的功能中。不确定你怎么想象Function App可以在没有任何凭证的情况下获得令牌。

你的第二部分

  

......想法是Azure功能推送状态信息   进入背板主题。但遗憾的是SignalR使用未知编码。   所以这种解决方法是不可能的。

使用ServiceBus作为signalR的背板,您正走在正确的道路上。但是,这是设计用于帮助在横向扩展部署(通常是云的所有内容)上同步所有signalR集线器,而不是让客户将消息推送到集线器。这些是仅由signalR集线器使用的系统消息,以确保每个人都知道一切。当走向云端并且规模扩大时 - 无论如何你都需要背板。