AAD B2C自定义策略问题:无法将URL格式名称的声明加入令牌
我在Azure AD B2C中使用包含RestfulProvider技术配置文件的自定义策略,该策略会向基于.NET构建的CRM API发起请求获取声明,并将这些声明注入身份令牌和访问令牌。但其中一个声明存在问题——这个声明在CRM API的JSON响应中名称为http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata(因为后端用了System.Security.Claims的ClaimTypes),其他声明都能正常映射,只有这个URL格式的声明无法正常注入令牌。
OpenIdConnect的.WellKnown文档的claims_supported数组里已经包含了这个URL,但问题依旧。
已尝试的配置
声明架构(ClaimsSchema)配置
<ClaimsSchema> <ClaimType Id="userData"> <DisplayName>Unique user ID</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata"> <DisplayName>user full name</DisplayName> <DataType>string</DataType> </ClaimType> </ClaimsSchema>
输出声明(OutputClaim)配置
<OutputClaim ClaimTypeReferenceId="userData" PartnerClaimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata"></OutputClaim> <OutputClaim ClaimTypeReferenceId="http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata"></OutputClaim>
解决思路
方法1:通过声明转换重命名键
在自定义策略中添加声明转换,将API返回的URL格式声明转换为短名称,再映射到令牌中:
<ClaimsTransformations> <ClaimsTransformation Id="CopyUserDataClaim" TransformationMethod="CopyClaim"> <InputClaims> <InputClaim ClaimTypeReferenceId="http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata" TransformationClaimType="inputClaim" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="userData" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> </ClaimsTransformations>
在RestfulProvider技术配置文件的OutputClaimsTransformations节点引用该转换,之后在信赖方配置中直接输出userData声明即可。
方法2:优化RestfulProvider的声明映射逻辑
保留ClaimsSchema中仅短名称的声明定义,在RestfulProvider技术配置文件中显式指定PartnerClaimType为完整URL:
<!-- RestfulProvider技术配置文件内 --> <OutputClaim ClaimTypeReferenceId="userData" PartnerClaimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata" />
然后在信赖方配置中直接输出userData声明:
<OutputClaim ClaimTypeReferenceId="userData" />
这种方式避免重复声明定义带来的冲突,同时明确映射API返回的特殊格式键。
方法3:调整后端API的声明输出
如果允许修改CRM API代码,将该声明的输出键改为短名称(如userData),绕过URL格式键的解析问题。.NET代码示例:
// 替换原ClaimTypes.UserData的用法 var claim = new Claim("userData", userDataValue);
内容的提问来源于stack exchange,提问作者Arpan3t

