我可以从 Azure AD 为我的应用程序获取 id_token 吗?

Can I get an id_token from Azure AD for my app?

使用 Azure AD 中的 client_credentials 流程,我无法为我的应用检索 id_token。

我正在尝试使用 Azure AD OAuth/OpenID 端点,运行 遇到一些问题。

我通过 Graph API(测试端点,但仍然是)创建了一个配置最少的简单应用程序。我已经删除了所有 headers 并在下面的代码片段中匿名化:

curl -X POST \
  https://graph.microsoft.com/beta/applications \
  -d '{
    "displayName": "App Name",
    "passwordCredentials": [
        {
            "endDateTime": "2299-12-30T23:00:00Z",
            "startDateTime": "2019-02-14T20:19:14.686691Z",
            "secretText": "<SOME KEY>",
            "displayName": "Client Secret"
        }
    ]
}'

在 Azure AD 的响应中,我得到一个 appId:

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#applications/$entity",
    "id": "<SOME GUID>",
    "deletedDateTime": null,
    "isFallbackPublicClient": null,
    "appId": "<SOME GUID>",
    ...

这足以让我能够从 v1 OAuth 端点检索 access_token:

curl -X POST \
  https://login.microsoftonline.com/tenant_id/oauth2/token \
  -d 'client_id=appId&client_secret=secretText&grant_type=client_credentials'

回复:

{
    "token_type": "Bearer",
    "expires_in": "3600",
    "ext_expires_in": "3600",
    "expires_on": "1550220412",
    "not_before": "1550216512",
    "resource": "00000002-0000-0000-c000-000000000000",
    "access_token": "<JWT access token>"
}

因为我没有在调用中指定资源,所以我得到了默认的 Graph API 资源。

现在,我还想为我的应用程序获得一个 id_token。我已经能够从其他 OpenID 提供商处获得这些令牌。但是,OpenID Connect 核心规范。让我有理由认为 id_tokens 仅适用于最终用户,而不适用于应用程序:

"The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims"

(来自 https://openid.net/specs/openid-connect-core-1_0.html#IDToken

resource=openid 添加到 POST 到上面的令牌端点将不起作用,因为 openid 是一个范围,而不是资源。

切换到 v2 端点后,我可以访问范围参数。我可以通过设置 scope=https://graph.microsoft.com/.default 从那里获取访​​问令牌,明确请求我默认通过 v1 端点获得的访问权限。

但是,将范围设置为例如 scope=https://graph.microsoft.com/.default openid 并没有为我的应用程序提供 id_token,并且访问令牌看起来与之前的调用相同。

仅尝试 scope=openid 会出现以下来自 Azure AD 的错误:

AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope openid is not valid.

所有这些结合起来让我相信我使用的 OpenID 提供者并通过 client_credentials 流程发布了 id_tokens 正在违反规范,并且 id_tokens 可以只能为最终用户获取(使用 authorization_code 流程让我从 Azure AD 获得 id_token 我自己没有任何问题)。

这是一个正确的结论,还是我可以强制 Azure AD 向应用程序和最终用户发出 id_tokens?

您不能使用客户端凭据流程获取 id_token 应用程序专用,它仅 returns access_token。

用户登录时发出id_token。客户端凭证流没有用户,因此没有发出 id_token。

您需要使用 authorization code grant or openID connect 之类的流程来让用户登录。响应将包含 id_token。