Azure AD中的自定义声明在JWT中的应用

11

我有一个Azure AD应用程序,正在尝试向JWT添加自定义声明。 我正在使用Azure的声明映射功能为我的特定应用程序,并更新了Azure门户中的应用程序清单以包括可选声明。 但是,当我登录并查看解码的访问令牌时,声明在令牌中不存在。 我没有找到关于使用扩展属性作为声明的文档,但从我找到的内容来看,它应该遵循相同的模式,但实际效果并不如预期。

当用户登录时,如何将源自AD用户对象中的自定义属性的自定义声明添加到JWT?

提前感谢!

重新创建步骤

  1. 使用Azure AD Graph API注册目录扩展

请求:

POST https://graph.windows.net/mytenant.onmicrosoft.com/applications/<application-object-id>/extensionProperties?api-version=1.5

正文:

{
   "name": "customUserRoles",
   "dataType": "String",
   "targetObjects": ["User"]
}
  • 为指定的AD用户写入扩展值
  • 请求:

    PATCH https://graph.windows.net/mytenant.onmicrosoft.com/users/user123@mytenant.onmicrosoft.com?api-version=1.5

    正文:

    {
       "extension_<appId>_customUserRoles": "My Custom Role 1, Another Role 2"
    }
    
    1. 在PowerShell中,我安装了Azure AD模块:Install-Module -Name AzureADPreview
    2. 创建一个Azure AD策略
    New-AzureADPolicy -Definition @('{"ClaimsMappingPolicy":{"Version": 1, "IncludeBasicClaimSet": "true", "
    ClaimsSchema": [ { "Source": "user", "ID": "extension_<appId>_customUserRoles", "JwtClaimType": "customUserRoles" } ] } }') -DisplayName "customUserRoles" -Type "ClaimsMappingPolicy"
    
    1. 将策略添加到服务主体
    Add-AzureADServicePrincipalPolicy -Id <service-principla-id> -RefObjectId <azure-ad-policy-id>
    
    1. 在Azure门户中,导航到Azure AD -> 应用程序注册 -> 我的应用程序 -> Manifest
    2. 更新以下属性
    {
       ...
       "acceptMappedClaims: true,
       "optionalClaims": {
          "idToken": [
             {
                "name": "extension_<appId>_customUserRoles",
                "source": "user",
                "essential": false,
             }
          ],
          "accessToken": [
             {
                "name": "extension_<appId>_customUserRoles",
                "source": "user",
                "essential": false,
             }
          ],
          "samlToken": []
       }
    }
    
    1. 保存文件
    2. 导航到 https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/authorize?client_id=<appId>&response_type=token&resource=https://mytenant.sharepoint.com 并使用 Azure AD 用户账户 user123@mytenant.onmicrosoft.com 登录
    3. 在 URL 中,复制 access_token 参数的值
    4. 导航到 https://jwt.ms 并将访问令牌粘贴到文本区域中
    5. 在解码的令牌部分,自定义声明 customUserRoles 不存在

    我期望能在解码的令牌中看到一个名为 customUserRolesextn.customUserRoles 的新声明。

    我错过了哪些步骤?在整个过程中我没有收到任何错误提示,但它似乎没有按照文档所述的那样工作。


    参考资料

    我已经阅读了微软关于以下主题的文档:

    可选声明: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims

    声明映射: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-claims-mapping


    我还阅读了各种与此相关的论坛帖子和博客文章:

    https://devonblog.com/cloud/azure-ad-adding-employeeid-claims-in-azure-ad-jwt-token/

    http://www.redbaronofazure.com/?p=7566

    https://social.msdn.microsoft.com/Forums/en-US/3e5114b6-24d6-4c60-b72b-b4c90baeecac/access-token-missing-optional-claims-that-are-schema-extensions-implicit-grant-flow

    https://social.msdn.microsoft.com/Forums/en-US/dbeeed63-8d3f-4c27-b416-431f9fe6c729/providing-directory-extension-optional-claims-and-returning-value-within-token?forum=WindowsAzureAD


    我认为您无法在未创建的API的访问令牌中获取自定义声明。据我了解,针对您应用程序的API的访问令牌以及您的应用程序接收到的ID令牌可能会包含它们。 - juunas
    如果指定的声明具有值,那么它将显示在令牌中。空值完全从标记中过时。通过调用graph.microsoft.com beta端点检查用户配置文件中的值。例如:https://graph.microsoft.com/beta/users/bece0bec-5c80-4295-9275-08b072e74z10并查看该值。 - Pramod Lawate
    2个回答

    7
    根据官方文档

    访问令牌始终使用资源的清单生成,而不是客户端。 因此,在请求中...scope=https://graph.microsoft.com/user.read...,资源是Graph。 因此,访问令牌是使用Graph清单创建的,而不是客户端的清单。 更改应用程序的清单永远不会导致Graph的令牌看起来不同。 为了验证accessToken更改是否生效,请为您的应用程序请求令牌,而不是另一个应用程序。

    根据您的要求,如果您想对资源为SharePoint Online的访问令牌进行更改,则不可能。SharePoint Online是由MSFT创建和管理的多租户应用程序。

    根据这篇文档,我也为您进行了一些研究。同样,您应该控制服务端应用程序以使其发生变化。

    这是我的策略角色分配命令:

    $nsp = New-AzureADPolicy -Definition @('{"ClaimsMappingPolicy":{"Version":1,"IncludeBasicClaimSet":"true", "ClaimsSchema": [{"Source":"user","ID":"mailnickname","JwtClaimType":"testclaim"}]}}') -DisplayName "StanCustomCliamDemo_surname" -Type "ClaimsMappingPolicy"
    
    Add-AzureADServicePrincipalPolicy  -RefObjectId $nsp.Id -Id '<obj id of service side app>'
    

    令牌结果:

    enter image description here

    另外,请注意extension_<appId>_customUserRoles不是有效的用户源ID。有关所有有效的用户源ID,请参见此处

    希望对你有所帮助。


    对于服务主体应用程序注册和自定义扩展字段,它对我不起作用。 - cortisol
    1
    @Stanley,我有一个类似的需求。我想要向Azure AD访问令牌添加一些自定义用户定义声明。我的需求与此完全匹配 https://stackoverflow.com/questions/60569243/how-to-set-custom-claims-to-aad-token-using-c-sharp-code - S.Chandra Sekhar
    4
    你是如何传递值 'stan' 的?这个值是在请求时动态传递的吗,当你尝试获取令牌时? - Darey

    0
    几年后才看到这个问题,但对于2023年来访的任何人。虽然没有特别详细的文档,但如果您想将extentionAttribute映射到JWT中,您需要在ClaimsSchema对象中使用属性ExtensionID而不是ID。
    所以:
    New-AzureADPolicy -Definition @('{"ClaimsMappingPolicy":{"Version": 1, "IncludeBasicClaimSet": "true", "ClaimsSchema": [ { "Source": "user", "ID": "extension_<appId>_customUserRoles", "JwtClaimType": "customUserRoles" } ] } }') -DisplayName "customUserRoles" -Type "ClaimsMappingPolicy"
    

    变成:
    New-AzureADPolicy -Definition @('{"ClaimsMappingPolicy":{"Version": 1, "IncludeBasicClaimSet": "true","ClaimsSchema": [ { "Source": "user", "ExtensionID": "extension_<appId>_customUserRoles", "JwtClaimType": "customUserRoles" } ] } }') -DisplayName "customUserRoles" -Type "ClaimsMappingPolicy"
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接