Azure Function 如何针对 SignalR 进行身份验证?
How can Azure Function authenticate against SignalR?
我正在编写类似 Web 应用程序的仪表板。外部系统的状态变化应该通过 SignalR 推送到浏览器。外部系统将其更新发送到 Azure 服务总线主题。我已经编写了一个 Azure 函数,它将由其中一个主题触发。该函数通过 SignalR .Net 客户端库连接到 SignalR 集线器,并将消息转发到集线器。集线器然后将消息发送到浏览器。
现在这工作正常。下一步是为 SignalR 集线器启用身份验证。 Web 应用程序的其他部分需要身份验证。用户使用他的 Azure AD 凭据登录。
问题是 Azure 函数如何针对 SignalR 进行身份验证?在 Azure Function App 的应用程序设置中保存一些凭据是不行的。
我已经研究了 SignalR 横向扩展技术的解决方法。我们可以将服务总线主题配置为背板。每个 SignalR 中心将消息的副本发送到主题中,以便中心的其他实例获取消息并将其向下推送到其连接的客户端。这个想法是 Azure 函数将状态信息推送到背板主题中。但遗憾的是 SignalR 使用未知编码。所以这个解决方法是不可能的。
@astaykov 回答的详细信息
将应用角色添加到 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"
}
],
- 将 Azure Function App 的应用注册与上述应用角色相关联。确保 Azure Function App 的注册类型为 Web app/API.
在Azure Function App的应用注册中创建key,获取token时使用
var ctx = new AuthenticationContext(tenant);
var cred = new ClientCredential(functionAppRegistrationId, key);
AuthenticationResult result = await ctx.AcquireTokenAsync(signalRRegistrationId, cred);
- 在查询字符串中使用标记。在互联网上搜索 Bearer Authentication SignalR。
你提出了两个问题。所以我会分开处理。
The question is how can the Azure function authenticate against
SignalR? Saving some credentials in the app settings of the Azure
Function App is a no go.
正如@GreameMiller 已经提到的,您应该查看使用 OAuth Bearer Token 对 SignalR 进行身份验证。对于您的 Azure Function App,您可以 create a Service Principal in your Azure AD and use that to get a valid Token for your SignalR (which has to be anyway another Application in Azure AD,或与您的 Web 应用相同)。后者您可能已经完成,您将需要获得前者。
一件非常重要的事情 - 一旦您获得了 "applications" (Service Principals) in your Azure AD you have to make sure that the "Function App Service Principal" has access to the "SignalR Web App" by explicitly granting those permission in the Azure AD Portal. Again from that article,您必须转到 "Function App" 应用程序的配置设置并确保配置 "Permissions to other applications"。如果您已正确配置您的 WebApp(使用 SignalR),您将在可用应用程序列表中看到只有选项的配置 - 访问 您的应用程序名称 。您必须使用 Application Permissions
而 而不是 Delegated Permissions
。
剩下的工作是标准的 OAuth2 客户端编程 - 客户端 ID + 客户端密码。但是,是的,您必须将它们保留在 Function App 的功能中。不确定您如何想象 Function App 可以在没有任何凭据的情况下获得令牌。
你的第二部分
... The idea was that the Azure function pushes the status information
into the backplane topic. But sadly SignalR uses an unknown encoding.
So this workaround is not possible.
您使用 ServiceBus 作为 signalR 的背板走在正确的道路上。但是,此设计旨在帮助在横向扩展部署(通常是云)上同步所有 signalR 集线器,而不是让您的客户端将消息推送到集线器。这些是仅由 signalR 集线器使用的系统消息,以确保每个人都知道一切。当走向云端和规模化时——无论如何你都需要那个背板。
我正在编写类似 Web 应用程序的仪表板。外部系统的状态变化应该通过 SignalR 推送到浏览器。外部系统将其更新发送到 Azure 服务总线主题。我已经编写了一个 Azure 函数,它将由其中一个主题触发。该函数通过 SignalR .Net 客户端库连接到 SignalR 集线器,并将消息转发到集线器。集线器然后将消息发送到浏览器。
现在这工作正常。下一步是为 SignalR 集线器启用身份验证。 Web 应用程序的其他部分需要身份验证。用户使用他的 Azure AD 凭据登录。
问题是 Azure 函数如何针对 SignalR 进行身份验证?在 Azure Function App 的应用程序设置中保存一些凭据是不行的。
我已经研究了 SignalR 横向扩展技术的解决方法。我们可以将服务总线主题配置为背板。每个 SignalR 中心将消息的副本发送到主题中,以便中心的其他实例获取消息并将其向下推送到其连接的客户端。这个想法是 Azure 函数将状态信息推送到背板主题中。但遗憾的是 SignalR 使用未知编码。所以这个解决方法是不可能的。
@astaykov 回答的详细信息
将应用角色添加到 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" } ],
- 将 Azure Function App 的应用注册与上述应用角色相关联。确保 Azure Function App 的注册类型为 Web app/API.
在Azure Function App的应用注册中创建key,获取token时使用
var ctx = new AuthenticationContext(tenant); var cred = new ClientCredential(functionAppRegistrationId, key); AuthenticationResult result = await ctx.AcquireTokenAsync(signalRRegistrationId, cred);
- 在查询字符串中使用标记。在互联网上搜索 Bearer Authentication SignalR。
你提出了两个问题。所以我会分开处理。
The question is how can the Azure function authenticate against SignalR? Saving some credentials in the app settings of the Azure Function App is a no go.
正如@GreameMiller 已经提到的,您应该查看使用 OAuth Bearer Token 对 SignalR 进行身份验证。对于您的 Azure Function App,您可以 create a Service Principal in your Azure AD and use that to get a valid Token for your SignalR (which has to be anyway another Application in Azure AD,或与您的 Web 应用相同)。后者您可能已经完成,您将需要获得前者。
一件非常重要的事情 - 一旦您获得了 "applications" (Service Principals) in your Azure AD you have to make sure that the "Function App Service Principal" has access to the "SignalR Web App" by explicitly granting those permission in the Azure AD Portal. Again from that article,您必须转到 "Function App" 应用程序的配置设置并确保配置 "Permissions to other applications"。如果您已正确配置您的 WebApp(使用 SignalR),您将在可用应用程序列表中看到只有选项的配置 - 访问 您的应用程序名称 。您必须使用 Application Permissions
而 而不是 Delegated Permissions
。
剩下的工作是标准的 OAuth2 客户端编程 - 客户端 ID + 客户端密码。但是,是的,您必须将它们保留在 Function App 的功能中。不确定您如何想象 Function App 可以在没有任何凭据的情况下获得令牌。
你的第二部分
... The idea was that the Azure function pushes the status information into the backplane topic. But sadly SignalR uses an unknown encoding. So this workaround is not possible.
您使用 ServiceBus 作为 signalR 的背板走在正确的道路上。但是,此设计旨在帮助在横向扩展部署(通常是云)上同步所有 signalR 集线器,而不是让您的客户端将消息推送到集线器。这些是仅由 signalR 集线器使用的系统消息,以确保每个人都知道一切。当走向云端和规模化时——无论如何你都需要那个背板。