我可以从 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。
使用 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。