从 PowerApp(或逻辑应用程序)调用 AAD 保护的 Azure 函数
Call AAD Protected Azure Function from PowerApp (or Logic App)
我有一个 Azure Function 设置为使用 AAD 身份验证(最新(非经典)方法),当我使用 Postman 或自定义连接器。我已关注有关设置自定义连接器的 Microsoft Docs 文章。
我的初始测试包括以下内容:
- 创建了一个新的 Azure Function App
- 为函数应用程序设置系统分配的 MSI
- 使用 AzureAD 设置身份验证(经典方法)
- 在 AzureAD 中创建额外的应用程序注册(用于自定义连接器)并执行必要的 configuration/consent
- 为 PowerApps 创建了自定义连接器
- 在自定义连接器
中成功测试
虽然这在使用经典身份验证方法配置时有效,但我随后在 Function App 中以新方式配置身份验证,这导致我的所有请求都 return 401。当我配置 Function App 以使用a 302 表示未经身份验证的请求,我可以使用针对 HTTP 触发功能的浏览器请求进行身份验证。但是,如果我尝试使用 Postman、测试自定义连接器或连接到逻辑应用程序中的函数,我总是会收到 401。所有身份验证配置都显示正确并且用户分配已配置。
我已经在寻找教程或其他已配置 PowerApps 连接与安全 Azure 函数的教程,但我无法找到我要找的内容。如果可能的话,我想使用最新的方法来设置身份验证,但如果不行,另一种方法是重新创建 Function App 并通过经典方法设置身份验证(注意:一旦你配置了新的身份验证方法,你就可以'不要返回并通过经典模式进行设置)。
更新:也想添加一些屏幕截图:
在 Authentication
部分,我将其设置为 需要身份验证(注意:当更改为 不需要身份验证 ,api 调用工作正常)。
该应用程序公开了 user_impersonation
api,如文档中所述(自定义应用程序注册已获得此 api 的授权)
自定义应用程序注册(即 连接器 应用程序注册)设置为使用 api 并获得同意。我已经生成了一个 client secret 供 Postman 使用。
在 LINQPad 中,我拼凑了一些代码以使用 connector app reg 获取 Access Token
。但是,我仍然遇到相同的 401 错误。我尝试同时使用 hostname 和 Function app auth app id - 两者都导致了 401。令牌成功返回,但是调用功能失败。
更新 #2:解决 PowerApp 自定义连接器问题
遵循@bowman-zhu 解决方案(从 Issuer URL 中删除 /v2.0
)后,我能够克服 401 错误。我的下一步是再次测试自定义连接器。由于这是最初的痛点,我想提供解决方案的详细信息。
最初,我仍然遇到错误,所以我决定从 Azure Active Directory
切换为身份提供者,而是使用 Generic Oauth 2
。
按照 Microsoft 文档创建自定义连接器后,Client id
和 Client secret
特定于 连接器应用程序注册 。 Authorization URL
和 Token URL
也从应用程序注册中删除(即使它们是 v2.0,它们仍然有效)。我对 Refresh URL
使用了与 Authorization URL 相同的值。范围是 <guid>/.default
(其中 是函数应用程序授权应用程序注册的应用程序 ID)。
验证和更新连接器后,我测试了其中一个 API 调用,最终一切都按预期工作。
更新:
检查您的发行人URL:
或者将 accessTokenAcceptedVersion 更改为 2:
无论如何,请确保问题 url 版本相同。
(我发现Authentication还有很多问题,很多东西不会自动配置。)
原答案:
这是你遇到的问题:
您需要授权:
例如,如果您使用 python,则:
1、最新的Authentication不会自动暴露你的function app,所以你需要添加:
1、创建客户端广告应用访问上面的api。
2,使用如下代码获取令牌(客户端 ID 和密码是从上面的广告应用程序获取的):
import requests
from azure.identity import ClientSecretCredential
import json
client_id = 'xxx'
tenant_id = 'xxx'
client_secret = 'xxx'
subscription_id = 'xxx'
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)
print(credential.get_token('https://0416bowman.azurewebsites.net/.default'))
accesstoken = str(credential.get_token('https://0416bowman.azurewebsites.net/.default'))[19:1141]
print(accesstoken)
3、将access token添加到Authorization header中,如果你使用的是postman,你应该这样做:
下面url可以让你检查token是否正确:
我有一个 Azure Function 设置为使用 AAD 身份验证(最新(非经典)方法),当我使用 Postman 或自定义连接器。我已关注有关设置自定义连接器的 Microsoft Docs 文章。
我的初始测试包括以下内容:
- 创建了一个新的 Azure Function App
- 为函数应用程序设置系统分配的 MSI
- 使用 AzureAD 设置身份验证(经典方法)
- 在 AzureAD 中创建额外的应用程序注册(用于自定义连接器)并执行必要的 configuration/consent
- 为 PowerApps 创建了自定义连接器
- 在自定义连接器 中成功测试
虽然这在使用经典身份验证方法配置时有效,但我随后在 Function App 中以新方式配置身份验证,这导致我的所有请求都 return 401。当我配置 Function App 以使用a 302 表示未经身份验证的请求,我可以使用针对 HTTP 触发功能的浏览器请求进行身份验证。但是,如果我尝试使用 Postman、测试自定义连接器或连接到逻辑应用程序中的函数,我总是会收到 401。所有身份验证配置都显示正确并且用户分配已配置。
我已经在寻找教程或其他已配置 PowerApps 连接与安全 Azure 函数的教程,但我无法找到我要找的内容。如果可能的话,我想使用最新的方法来设置身份验证,但如果不行,另一种方法是重新创建 Function App 并通过经典方法设置身份验证(注意:一旦你配置了新的身份验证方法,你就可以'不要返回并通过经典模式进行设置)。
更新:也想添加一些屏幕截图:
在 Authentication
部分,我将其设置为 需要身份验证(注意:当更改为 不需要身份验证 ,api 调用工作正常)。
该应用程序公开了 user_impersonation
api,如文档中所述(自定义应用程序注册已获得此 api 的授权)
自定义应用程序注册(即 连接器 应用程序注册)设置为使用 api 并获得同意。我已经生成了一个 client secret 供 Postman 使用。
在 LINQPad 中,我拼凑了一些代码以使用 connector app reg 获取 Access Token
。但是,我仍然遇到相同的 401 错误。我尝试同时使用 hostname 和 Function app auth app id - 两者都导致了 401。令牌成功返回,但是调用功能失败。
更新 #2:解决 PowerApp 自定义连接器问题
遵循@bowman-zhu 解决方案(从 Issuer URL 中删除 /v2.0
)后,我能够克服 401 错误。我的下一步是再次测试自定义连接器。由于这是最初的痛点,我想提供解决方案的详细信息。
最初,我仍然遇到错误,所以我决定从 Azure Active Directory
切换为身份提供者,而是使用 Generic Oauth 2
。
Client id
和 Client secret
特定于 连接器应用程序注册 。 Authorization URL
和 Token URL
也从应用程序注册中删除(即使它们是 v2.0,它们仍然有效)。我对 Refresh URL
使用了与 Authorization URL 相同的值。范围是 <guid>/.default
(其中 是函数应用程序授权应用程序注册的应用程序 ID)。
验证和更新连接器后,我测试了其中一个 API 调用,最终一切都按预期工作。
更新:
检查您的发行人URL:
或者将 accessTokenAcceptedVersion 更改为 2:
无论如何,请确保问题 url 版本相同。
(我发现Authentication还有很多问题,很多东西不会自动配置。)
原答案:
这是你遇到的问题:
您需要授权:
例如,如果您使用 python,则:
1、最新的Authentication不会自动暴露你的function app,所以你需要添加:
1、创建客户端广告应用访问上面的api。
2,使用如下代码获取令牌(客户端 ID 和密码是从上面的广告应用程序获取的):
import requests
from azure.identity import ClientSecretCredential
import json
client_id = 'xxx'
tenant_id = 'xxx'
client_secret = 'xxx'
subscription_id = 'xxx'
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)
print(credential.get_token('https://0416bowman.azurewebsites.net/.default'))
accesstoken = str(credential.get_token('https://0416bowman.azurewebsites.net/.default'))[19:1141]
print(accesstoken)
3、将access token添加到Authorization header中,如果你使用的是postman,你应该这样做:
下面url可以让你检查token是否正确: