AAD中使用IfEmpty ClaimsTransformation生成JWT自定义声明的问题
如何使用IfEmpty声明转换为JWT添加自定义fallback声明
需求说明
需要为JWT令牌添加自定义声明prn,逻辑规则如下:
- 若存在
userprincipalname声明,则将其作为prn的值 - 若
userprincipalname声明缺失,则使用objectid作为prn的值
错误配置分析
你之前的配置存在两个核心问题:
- 首次配置错误传入了多个无关输入声明(
inputClaim1/inputClaim2/inputClaim3),但IfEmpty仅需要两个输入参数:要检查的声明、fallback替代声明 - 二次配置错误设置了多个输出声明,
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
相关产品推荐
相关产品推荐

