资源所有者密码凭据令牌在 Azure Function App 上导致 401

Posted

技术标签:

【中文标题】资源所有者密码凭据令牌在 Azure Function App 上导致 401【英文标题】:Resource Owner Password Credentials token results in 401 on Azure Function App 【发布时间】:2021-03-06 05:34:18 【问题描述】:

我想将 Azure AD 的资源所有者密码凭据流用于我的函数应用。函数应用程序已启动并正在运行。为应用配置 Azure AD 身份验证后,我的请求会被 401 Unauthorized 拒绝,但没有关于错误的更多详细信息。

我还应该强调,我可以从我的租户的身份验证端点获取新令牌。只是当我尝试从curl 调用函数时,这些令牌被拒绝。当我使用浏览器和相同的凭据登录时,我可以访问该功能。

澄清:通过 API 获取令牌是可行的,但这些令牌随后会被函数应用的 AAD 身份验证拒绝。通过浏览器,我获得了可以让我登录到函数应用程序的令牌。


我做了什么:

创建函数应用

基本GET 请求,无需授权或通过浏览器授权即可工作。

在 Azure AD 中创建应用注册

隐式授权:访问 + ID 令牌 支持的帐户类型:单租户 允许公共客户流:是 在清单中:"oauth2AllowImplicitFlow": true, 范围:我的 API 的自定义 user_impersonation 范围 API:我在这里添加了我的函数应用,其范围为 user_impersonation

将函数应用配置为通过 AAD 对用户进行身份验证

管理模式:高级 Client ID:上述应用注册的客户端ID 允许的令牌受众:我的函数的 URL

重现步骤:

获取新的access_token

向https://login.microsoftonline.com//oauth2/v2.0/token 和以下参数发出POST 请求:

clientId:Azure AD 中应用注册的客户端 ID scope: user.read openid profile offline_access https://<my-function>.azurewebsites.net/user_impersonation username:用户的邮箱 password:用户的密码 grant_type: password

这将返回access_token。我不会在这里发布它,但我可以根据要求分享详细信息。

调用受保护的 API

使用以下标头参数向https://<my-function>.azurewebsites.net/api/test 发出GET 请求:

Authorization: Bearer <access_token>

当然,非常感谢任何帮助。重要的是要注意,用户无论如何都不能以交互方式登录。我很清楚 ROPC 流程的缺陷和缺点,但这是使用 Azure AD 解决此特定用例的唯一方法。

这是我之前咨询过的一些资源。当然,我可能忽略了一个关键点:

https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc?tabs=app-reg-ga(不使用 AAD B2C,但可能足够相似。但是这里提到的步骤有效。)

【问题讨论】:

您使用的帐户是否启用了 MFA? (另外,您必须确认 MFA 是否在组织网络之外被禁用) 不,很遗憾,这不是问题所在。我想我一开始就无法在启用 MFA 的情况下获取令牌。 您提到只有通过浏览器进行身份验证才能获取令牌。浏览器传递设备信息,可以配置在传递设备信息时绕过 MFA。这就是我怀疑它可能是 MFA 的原因。 作为 curl - 不传递设备信息并且可能受到 MFA 的影响。 快速检查是尝试在私人/隐身浏览器会话中登录 - 检查您是否能够在没有任何 MFA 提示的情况下登录。 【参考方案1】:

我似乎已经修复了它。解决方法是多试错,也许有更简单的方法。

Azure AD 应用注册

只选择访问令牌,反正我们不需要 ID 令牌。 在清单中设置"accessTokenAcceptedVersion": 2 使用建议的 api://... 应用程序 ID

功能应用

将客户端 ID 和允许的令牌受众都设置为 AAD 应用注册中的应用程序 ID,但没有前导 api:// 方案。

获取令牌

指定范围为api://.../user_impersonation

完成上述所有步骤后,我可以成功进行身份验证,然后才能访问我的函数应用。下一个挑战是从请求中读取经过身份验证的用户名。但这可能是 SO 上另一个线程的主题。

【讨论】:

以上是关于资源所有者密码凭据令牌在 Azure Function App 上导致 401的主要内容,如果未能解决你的问题,请参考以下文章

.NET Core 3.1 IdentityServer4:使用资源所有者密码凭据授予时获取无效访问令牌

Oauth 刷新令牌授予类型

使用 Azure Active Directory 客户端凭据流控制身份验证令牌的到期

Azure KeyVault:Azure.Identity.CredentialUnavailableException:DefaultAzureCredential 无法从包含的凭据中检索令牌

如何在使用 OAuth2 的资源所有者密码凭据授予类型时对客户端凭据保密

OAuth 2.0 中资源所有者密码凭据授予类型的用途是啥?