Azure API 管理:使用 Oauth2 401 的授权给出“未经授权。访问令牌丢失或无效。”

Posted

技术标签:

【中文标题】Azure API 管理:使用 Oauth2 401 的授权给出“未经授权。访问令牌丢失或无效。”【英文标题】:Azure API Management: authorization with Oauth2 401 gives "Unauthorized. Access token is missing or invalid." 【发布时间】:2020-04-10 03:55:43 【问题描述】:

我想通过 Azure API 管理公开一些 API(逻辑应用程序、函数)。 它们工作正常,所以我决定添加 OAuth2 自动化。

我一步一步跟着https://docs.microsoft.com/fr-fr/azure/api-management/api-management-howto-protect-backend-with-aad:

在 Azure AD 中注册一个应用程序(后端应用程序)来表示 API。 在 Azure AD 中注册另一个应用程序(客户端应用程序)以表示需要调用 API 的客户端应用程序。 在 Azure AD 中,授予允许客户端应用调用后端应用的权限。 将开发者控制台配置为使用 OAuth 2.0 用户授权调用 API。 添加 validate-jwt 策略以验证每个传入请求的 OAuth 令牌。 也可以使用 Postman 进行测试

在“validate-jwt”策略步骤之前一切正常。 当我添加它时,我得到一个“401 - 未经授权。访问令牌丢失或无效。” 我可以在 Developer Console 和 Postman 中获取令牌,但只要我执行 API 调用...401!

当我使用 jwt.ms 检查令牌的内容时,我注意到 aud 参数与后端应用程序 ID 无关。 令牌中的值为“00000003-0000-0000-c000-000000000000”,而后端应用ID为“16caXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXc0”。

我的想法不多了,需要一些 Azure 大师的帮助! 非常感谢您的帮助...

根据 MS 文档,在入站策略下方:

<policies>
    <inbound>
        <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
            <openid-config url="https://login.microsoftonline.com/MY_AD_TENANT_ID/.well-known/openid-configuration" />
            <required-claims>
                <claim name="aud">
                    <value>MY8BACKEND_APP_ID_GUID</value>
                </claim>
            </required-claims>
        </validate-jwt>
    </inbound>
    <backend>
        <forward-request />
    </backend>
    <outbound />
    <on-error />
</policies>

Screen cap of the Postman screen where I get the token (this works, but then when I send the request --> 401)

Screen cap of aud param in jwt.ms

【问题讨论】:

【参考方案1】:

几年前我在验证 Azure AD 令牌时遇到了一些问题 - 请参阅我的 write up。

我怀疑问题出在 JWT 标头中的随机数。

【讨论】:

嗨,加里,感谢您的写作,这绝对让我走上了正轨。正如您在其中解释的那样,“如果 JWT 的标头中有 nonce 字段,那么它仅适用于 Microsoft 开发的 Azure API。这些令牌需要特殊处理,并且始终无法通过基于标准的验证。” --> 就是这样。不幸的是,我计划通过 APIM 公开逻辑应用程序,因此无法添加自制代码来验证 jwt。 也许是因为我几周前开始使用 APIM/Functions/Logic Apps,但实际上我在这里没有得到一些东西:MS 提供的 jwt 令牌不能通过自己的入站策略 (validate-jwt) 验证?怎么会?注意:另一个有趣的事情是,当我使用从中获取 jwt 令牌的 Postman 时,我使用范围“user.read”(我创建的那个),并且在 jwt 中,范围是“User.Read profile openid email " 如果我没记错的话,几年前我停止使用 v2 OAuth 端点并使用 v1 端点——为了从 JWT 标头中删除 nonce,以便我可以验证令牌。我没有使用图形 API,只是尝试像您一样使用自定义 API。 我同意你的沮丧。如果微软默认遵循 OAuth 2.0 和 Open Id Connect 标准会容易得多。相反,他们不自然的供应商扩展使他们的技术难以用于常见用例。看起来很多人都在为此苦苦挣扎:github.com/AzureAD/microsoft-authentication-library-for-js/… 非常感谢加里!通过使用 v1 端点,不再需要 nonce,并且它可以立即在 Postman 和开发者控制台中运行!【参考方案2】:

您实际上并不需要检查 aud 参数的值。您可以一起删除required-claims,这样令牌的存在和签名仍然会得到验证。如果您想确保为您的应用颁发了令牌,只需找到包含应用 ID 的声明并在 name="..." 中使用它来匹配您的应用 ID 值。

【讨论】:

您好 Vitaliy,谢谢您的想法。我尝试了您提出的建议,但没有运气:我删除了对 aud 的检查,但我仍然有“401 - 未经授权。访问令牌丢失或无效。”。所以我想我的问题在其他地方,我找不到它(在开发人员门户中我看不到调试信息,也看不到活动日志:它显示“获取令牌”和“获取 SSO 令牌”调用,他们成功了)。 使用 Azure 门户中的测试控制台进行调用:打开 APIM 服务,转到 API,选择 API,选择操作,转到测试选项卡。确保将您的令牌添加到请求中。通过这种方式,您将获得呼叫跟踪并解释出了什么问题。 谢谢 Vitaliy,我试过了并获取了 ocp-apim-trace-location,它显示了一个有趣的片段:“on-error”:[ “source”:“validate-jwt”, “数据”:“消息”:“JWT 验证失败:IDX10511:签名验证失败。尝试的密钥:'Microsoft.IdentityModel.Tokens.X509SecurityKey,KeyId:piVlloQDSMKxh1m2ygqGSVdgFpA\r\n'。\nkid:'piVlloQDSMKxh1m2ygqGSVdgFpA'。\n异常捕获:\n ''。\ntoken: '\"typ\":\"JWT\",\"nonce\":\"Tuh4aIzD0u0CKgZg1\",\"alg\":\"RS256\", ], 嗨 Vitaliy,感谢您的帮助:Gary 为我指出了正确的方向(上一个答案中的 cmets)--> 通过使用 v1 端点而不是 v2,随机数在 jwt 中消失了,并且它在开发者控制台和 Postman 中都能立即运行。 嗨 Laurent - 只是为了回复您,我最近更新了我的 Azure Code Sample + Docs 以使用 2.0 端点。这很不直观,但我得到了它的工作。只是想我会回帖以防将来对您有用。问候..【参考方案3】:

如果使用 v2 版本端点,请转到 -> azure ad -> 应用注册 -> 选择后端应用 -> 清单 -> 更新属性 "accessTokenAcceptedVersion": 2,"

【讨论】:

以上是关于Azure API 管理:使用 Oauth2 401 的授权给出“未经授权。访问令牌丢失或无效。”的主要内容,如果未能解决你的问题,请参考以下文章

Azure API 管理:使用 Oauth2 401 的授权给出“未经授权。访问令牌丢失或无效。”

我正在尝试使用 OAuth2 保护探索 azure API 管理我无法理解它的工作流程

Azure API - 无法从 API 管理访问 API 网关 URL

Azure API 管理 - 如何刷新访问令牌后端 API?

使用 OAuth2.0 或 Azure Active Directory 保护 REST API

Azure api OAuth2 隐式流适用于 http 但不适用于 htt