使用Azure AD中的client_credentials流,我无法为我的应用检索id_token。
我正在试验Azure AD OAuth / OpenID终结点,并遇到了一些问题。
我通过Graph API(但仍为beta端点)以最少的配置创建了一个简单的应用程序。我删除了所有标头,并在以下代码段中将其匿名化:
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 Core规范。让我有理由认为id_tokens仅针对最终用户,而非应用程序:
“ ID令牌是一种安全令牌,其中包含有关使用客户端时授权服务器对最终用户的身份验证的声明以及可能的其他请求的声明”
(来自https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
将resource=openid
添加到POST到上面的令牌端点将不起作用,因为openid是作用域,而不是资源。
切换到v2端点,我可以访问scope参数。我可以通过设置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.
所有这些结合在一起使我相信,我已经使用并已通过client_credentials流发布了id_tokens的OpenID提供程序正在违反规范,并且id_tokens仅可用于最终用户(使用authorization_code流为我提供了一个id_token为我自己创建Azure AD,没有任何问题。
这是正确的结论,还是可以强制Azure AD向应用程序以及最终用户发出id_tokens?
答案 0 :(得分:1)
用户登录时会发出id_token。客户端credentail流没有用户,因此不会发出id_token。
您需要使用authorization code grant或openID connect之类的流来登录用户。响应将带有id_token。
答案 1 :(得分:0)