You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AAD中使用IfEmpty ClaimsTransformation生成JWT自定义声明的问题

如何使用IfEmpty声明转换为JWT添加自定义fallback声明

需求说明

需要为JWT令牌添加自定义声明prn,逻辑规则如下:

  • 若存在userprincipalname声明,则将其作为prn的值
  • 若userprincipalname声明缺失,则使用objectid作为prn的值

错误配置分析

你之前的配置存在两个核心问题:

  1. 首次配置错误传入了多个无关输入声明(inputClaim1/inputClaim2/inputClaim3),但IfEmpty仅需要两个输入参数:要检查的声明、fallback替代声明
  2. 二次配置错误设置了多个输出声明,IfEmpty只会生成一个结果声明

正确的声明映射策略配置

以下是符合要求的ClaimsMappingPolicy定义:

{
  "ClaimsMappingPolicy": {
    "Version": 1,
    "IncludeBasicClaimSet": "true",
    "ClaimsSchema": [
      // 声明需要用到的源数据(可选,用于明确依赖)
      {
        "Source": "user",
        "ID": "userprincipalname",
        "JwtClaimType": "upn"
      },
      {
        "Source": "application",
        "ID": "objectid",
        "JwtClaimType": "oid"
      },
      // 定义转换后的目标声明
      {
        "Source": "transformation",
        "TransformationID": "UseUpnOrObjectId",
        "ID": "prn",
        "JwtClaimType": "prn"
      }
    ],
    "ClaimsTransformations": [
      {
        "ID": "UseUpnOrObjectId",
        "TransformationMethod": "IfEmpty",
        "InputClaims": [
          // inputClaim: 要检查是否为空的核心声明
          {
            "ClaimTypeReferenceId": "userprincipalname",
            "TransformationClaimType": "inputClaim"
          },
          // outputClaimIfEmpty: 当inputClaim为空时的替代声明
          {
            "ClaimTypeReferenceId": "objectid",
            "TransformationClaimType": "outputClaimIfEmpty"
          }
        ],
        "OutputClaims": [
          // outputClaim: 最终生成的自定义声明
          {
            "ClaimTypeReferenceId": "prn",
            "TransformationClaimType": "outputClaim"
          }
        ]
      }
    ]
  }
}

配置说明

  • InputClaims字段:
    • inputClaim指定需要校验的目标声明(userprincipalname)
    • outputClaimIfEmpty指定校验为空时的替代声明(objectid)
  • OutputClaims字段:将转换结果映射到ClaimsSchema中定义的prn声明,最终会作为JWT的prn字段输出

创建策略并分配

1. 创建Azure AD策略

执行以下PowerShell命令(注意引号转义):

New-AzureADPolicy -Definition @('{"ClaimsMappingPolicy":{"Version":1,"IncludeBasicClaimSet":"true","ClaimsSchema":[{"Source":"user","ID":"userprincipalname","JwtClaimType":"upn"},{"Source":"application","ID":"objectid","JwtClaimType":"oid"},{"Source":"transformation","TransformationID":"UseUpnOrObjectId","ID":"prn","JwtClaimType":"prn"}],"ClaimsTransformations":[{"ID":"UseUpnOrObjectId","TransformationMethod":"IfEmpty","InputClaims":[{"ClaimTypeReferenceId":"userprincipalname","TransformationClaimType":"inputClaim"},{"ClaimTypeReferenceId":"objectid","TransformationClaimType":"outputClaimIfEmpty"}],"OutputClaims":[{"ClaimTypeReferenceId":"prn","TransformationClaimType":"outputClaim"}]}]}}') -DisplayName "UPNOrObjectIdAsPRN" -Type "ClaimsMappingPolicy"

2. 将策略分配给服务主体

替换为你的应用名称后执行:

# 获取目标服务主体
$sp = Get-AzureADServicePrincipal -Filter "displayName eq '你的应用名称'"
# 获取策略ID
$policy = Get-AzureADPolicy -Filter "displayName eq 'UPNOrObjectIdAsPRN'"
# 分配策略
Add-AzureADServicePrincipalPolicy -Id $sp.ObjectId -RefObjectId $policy.ObjectId

验证

获取应用的JWT令牌后,解码查看prn字段:

  • 当userprincipalname存在时,prn值与userprincipalname一致
  • 当userprincipalname缺失时,prn值与objectid一致

内容的提问来源于stack exchange,提问作者nik-lazer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:54:50