使用 azure oauth 客户端凭据流时如何添加可选声明以访问令牌

Dan*_*iel 6 azure oauth-2.0 azure-active-directory azure-authentication

在我的场景中,有一个带有凭据的 Azure 应用程序注册 ( client_app )。该应用程序用于请求 oauth2 访问令牌。第二个应用程序注册(main_app)是范围,它提供应用程序角色等。

我的目标是在 azure 端点上使用客户端凭据流请求令牌时,将来自client_app的信息包含在 jwt 令牌声明中。/oauth2/v2.0/token

这是一个令牌请求:

POST /<tenant id>/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
 
client_id=<Application ID of client_app>
&client_secret=<secret of client_app>
&scope=<Application ID URI of main_app + "/.default">
&grant_type=client_credentials
Run Code Online (Sandbox Code Playgroud)

令牌请求的响应是一个有效的令牌,包括(从main_appclient_approles授予的应用程序角色)、和声明。但我的可选声明丢失了audsubidtype: app

MS 文档指出,可以使用目录扩展包含可选声明

可选声明不支持架构和开放扩展,仅支持 AAD-Graph 样式目录扩展。此功能对于附加您的应用程序可以使用的其他用户信息非常有用 [...]

因此,我尝试向main_app ( )添加目录扩展,向main_appextension_<main_app ID>_someAttrName添加可选声明,并将值存储到client_app中的该目录扩展中。不幸的是,扩展值没有反映在令牌中。

我尝试在client_app本身 ( )上添加目录扩展,并使用ClaimsMappingPolicyextension_<client_app ID>_someAttrName将目录扩展映射到main_app。不幸的是,扩展值没有反映在令牌中。

在我看来,声明丢失了,因为它们不是源自用户对象。MS 文档提供了大量信息来添加可选声明,但大多数场景都涉及用户。source例如清单的可选声明属性:

声明的来源(目录对象)。扩展属性中有预定义的声明和用户定义的声明。如果源值为空,则声明是预定义的可选声明。如果源值为 user,则 name 属性中的值是用户对象的扩展属性。

据我了解,只有null并且"user"是支持的。我想包含源自应用程序注册 ( client_app ) 的目录扩展。由于我必须使用客户端凭据流(服务器到服务器),因此不需要用户参与。

那么,在使用客户端凭证流且不涉及用户对象时,如何向令牌添加自定义可选声明呢?涉及到一个应用程序对象。那么我需要如何配置声明来反映自定义应用程序数据(例如目录扩展)?

main_app的清单:

{
    "id": "<main_app ID>",
    "acceptMappedClaims": true,
    "accessTokenAcceptedVersion": 2,
    "appId": "<main_app APP ID>",
    "appRoles": [{
            "allowedMemberTypes": ["Application"],
            "isEnabled": true,
            "origin": "Application",
            "value": "readAll"
        },{
            "allowedMemberTypes": ["Application"],
            "isEnabled": true,
            "origin": "Application",
            "value": "writeAll"
        }],
    "identifierUris": ["api://<main_app ID>"],
    "optionalClaims": {
        "idToken": [],
        "accessToken": [            {
                "name": "extension_<main_app ID>_someAttrName",
                "source": "application", <-- propably invalid, "user" or null is supported
                "essential": false,
                "additionalProperties": []
            }, { ... }
        ],
    },
} /# trunced for readability
Run Code Online (Sandbox Code Playgroud)

client_app的清单:

{
    "id": "<client_app ID>",
    "accessTokenAcceptedVersion": null,
    "appId": "<client_app APP ID>",
    "passwordCredentials": [{...}],
    "extension_<main_app ID>_someAttrName": "some-string-value"
} /# trunced for readability
Run Code Online (Sandbox Code Playgroud)

我的 ClaimsMappingPolicydefinition如下所示:

"ClaimsMappingPolicy": { "Version": 1, "IncludeBasicClaimSet": "true",
        "ClaimsSchema": [ {
            "Source": "application",
            "ExtensionID": "extension_<client_app ID>_someAttrName",
            "JwtClaimType": "someAttrName"
        } ]
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 2

我联系了 Azure 支持工程师,他们告诉我,不可能包含源自应用程序注册的基于目录扩展的声明。他们没有详细说明,但回复如下:

抱歉,我们得知无法在 JWT 令牌中反映扩展声明。由于目录扩展无法添加到 servicePrincipal 对象中。

我假设使用客户端凭据流时请求实体是服务主体。