使用 Azure AD 通过 OAuth2 对 Azure API 管理进行身份验证

Posted

技术标签:

【中文标题】使用 Azure AD 通过 OAuth2 对 Azure API 管理进行身份验证【英文标题】:Authenticate Azure API Management with OAuth2 using Azure AD 【发布时间】:2021-04-04 09:18:00 【问题描述】:

我正在尝试通过阅读文章通过 AzureAD 使用 OAuth2 保护 APIM API:Protect a web API backend in Azure API Management by using OAuth 2.0 authorization with Azure AD

AzureAPIM - OAuth2

授权端点 URL (v1):https://login.microsoftonline.com/tenant/oauth2/authorize 令牌端点 URL (v1):https://login.microsoftonline.com/tenant/oauth2/token 客户端 ID:客户端应用 ID 重定向 URI:(已弃用的门户):https://xxx-api.portal.azure-api.net/docs/services/auth1/console/oauth2/authorizationcode/callback

AzureAD - 后端应用:

范围:Files.All

AzureAD - 客户端应用程序:

密钥:xxx 重定向网址:仅适用于 APIM 中已弃用的门户 (https://xxx-api.portal.azure-api.net/docs/services/auth1/console/oauth2/authorizationcode/callback)

对于演示会议 API,将验证 JWT 策略添加到入站处理,其中 3a0cf09b- 是租户 ID,b7c31179- 是后端应用程序 ID:

在开发者门户中,对 AzureAD 的身份验证成功并返回令牌:

但是调用 API 授权失败:

查看jwt.io中收到的token,发现"aud": "00000003-0000-0000-c000-000000000000"不是backend-app application id:


  "aud": "00000003-0000-0000-c000-000000000000",
  "iss": "https://sts.windows.net/3a0cf09b-xxx/",
  "app_displayname": "client-app",
  "appid": "05a245fb-xxx",
  "scp": "Files.Read User.Read profile openid email",
  "tenant_region_scope": "OC",
  "tid": "3a0cf09b-2952-4673-9ace-0e1bf69ee23a",
  "unique_name": "user1@xxx.onmicrosoft.com",

API 测试 HTTP 响应跟踪显示 validate-jwt 上的错误:

validate-jwt (-0.138 ms)

    "message": "JWT Validation Failed: Claim value mismatch: aud=b7c31179-xxx.."

aud 替换为令牌00000003-0000-0000-c000-000000000000 中的值或删除validate-jwt 策略中的required-claims 以使其正常工作。

有什么想法吗?

【问题讨论】:

【参考方案1】:

从你的报错来看,确实是401错误,也就是你的aud与你要调用的api不匹配,我用auth code flow给你做个简单的演示:

先暴露后端应用的api,添加客户端应用。

接下来,在“API 权限”下,让您的前端应用程序访问您的后端 api:

在“API 权限”下点击“添加权限”,然后点击“我的 API”选项卡。 找到您的后端应用程序并选择适当的范围。 点击“添加权限”。 为您的 API 授予管理员许可。

获取令牌:

解析令牌:

【讨论】:

谢谢卡尔。确认它正在使用 v2。为了测试,我手动从login.microsoftonline.comtenant/oauth2/v2.0/authorize 获得了authorization code,然后通过 Postman 从login.microsoftonline.comtenant/oauth2/v2.0/token 获得了access token【参考方案2】:

您似乎选择了OAuth2授权的v1端点而不是v2端点,因此访问令牌中aud的值应该像b7c31179-xxxx....而不是api://b7c31179-xxxx....。所以你获取访问令牌的步骤没有错误。

根据我这边的一些测试,这个问题的原因是你在 APIM 中配置 OAuth2.0 时没有指定参数resource 的值为 backend-app 应用程序 id。您所指的document 也提到了这一点(我测试时未指定此参数,它显示与您相同的问题)

因此,要解决此问题,请转到您的 APIM 并单击“OAuth 2.0”选项卡,编辑您创建的项目。添加参数resource,其值为后端应用程序ID。

注意:当您添加参数resource并点击“保存”按钮时,请再次打开该项目并检查“Client secret”框是否为空.当我在我这边测试时,添加参数resource后,“Client secret”框显示为空,这可能是该页面上的错误。如果“Client secret”为空,则在开发者门户中获取访问令牌时可能会显示The request body must contain the following parameter: 'client_assertion' or 'client_secret' 之类的错误消息。

【讨论】:

谢谢你。忘记在 APIM OAuth2 (v1) 中添加 resource=backend app id

以上是关于使用 Azure AD 通过 OAuth2 对 Azure API 管理进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

添加 Azure Ad Oauth2 JWT 令牌声明

刷新的 OAuth2 令牌具有无效签名 (Azure AD OAuth2)

使用 oAuth 和 SAML 代表 Azure AD

用于多个 WebApi 端点的 Azure AD 不记名令牌?

是否可以仅请求用户已在 Azure AD OAuth2 隐式流中同意的范围的子集?

Azure AD B2C 受众验证失败