如何在Azure AD B2C自定义策略中解析Graph API参数?
解决Graph API嵌套JSON响应的声明解析与类型转换问题
问题分析
你调用Graph API返回的是嵌套结构的JSON,lastPasswordChangeDateTime字段位于value数组的第一个对象中,而B2C的OutputClaim默认不支持直接通过数组索引的点语法(如value.0.lastPasswordChangeDateTime)提取嵌套字段,导致要么无法正确取值,要么只能拿到JSON字符串片段。同时需要将字符串日期转换为dateTime类型以支持后续声明转换。
解决方案步骤
1. 定义所需声明类型
在TrustFrameworkExtensions.xml中添加对应的声明类型,分别存储JSON对象字符串、日期字符串和最终的dateTime类型值:
<ClaimType Id="userValueObject"> <DisplayName>用户信息对象JSON</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="passwordChangeDateString"> <DisplayName>密码修改日期(字符串)</DisplayName> <DataType>string</DataType> </ClaimType> <ClaimType Id="passwordChangeDateTime"> <DisplayName>密码修改日期(DateTime)</DisplayName> <DataType>dateTime</DataType> </ClaimType>
2. 添加声明转换规则
添加两个声明转换:第一个解析JSON字符串提取日期字段,第二个将字符串转换为标准dateTime类型:
<ClaimsTransformations> <!-- 解析JSON对象字符串,提取日期字段 --> <ClaimsTransformation Id="ParseUserValueJson" TransformationMethod="ParseJson"> <InputClaims> <InputClaim ClaimTypeReferenceId="userValueObject" TransformationClaimType="inputJson" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="passwordChangeDateString" TransformationClaimType="lastPasswordChangeDateTime" /> </OutputClaims> </ClaimsTransformation> <!-- 将字符串日期转换为dateTime类型 --> <ClaimsTransformation Id="ConvertStringToDateTime" TransformationMethod="ConvertStringToDateTime"> <InputClaims> <InputClaim ClaimTypeReferenceId="passwordChangeDateString" TransformationClaimType="inputClaim" /> </InputClaims> <InputParameters> <InputParameter Id="inputFormat" DataType="string" Value="yyyy-MM-ddTHH:mm:ssZ" /> <InputParameter Id="outputFormat" DataType="string" Value="yyyy-MM-ddTHH:mm:ss.fffZ" /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="passwordChangeDateTime" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> </ClaimsTransformations>
3. 配置Graph API调用的TechnicalProfile
修改你的Graph API TechnicalProfile,先提取value数组的第一个对象为字符串,再依次执行声明转换:
<TechnicalProfile Id="GraphAPI-GetPasswordChangeDate"> <DisplayName>从Graph API获取密码修改日期</DisplayName> <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <Metadata> <Item Key="ServiceUrl">https://graph.microsoft.com/v1.0/users/{objectId}?$select=lastPasswordChangeDateTime</Item> <Item Key="AuthenticationType">Bearer</Item> <Item Key="SendClaimsIn">Url</Item> </Metadata> <OutputClaims> <!-- 提取value数组的第一个元素为JSON字符串 --> <OutputClaim ClaimTypeReferenceId="userValueObject" PartnerClaimType="value[0]" /> </OutputClaims> <OutputClaimsTransformations> <!-- 先解析JSON提取日期字符串,再转换为dateTime --> <OutputClaimsTransformation ReferenceId="ParseUserValueJson" /> <OutputClaimsTransformation ReferenceId="ConvertStringToDateTime" /> </OutputClaimsTransformations> <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> </TechnicalProfile>
为什么之前的配置无效?
PartnerClaimType="value.0.lastPasswordChangeDateTime":B2C的REST Provider不支持这种点语法访问数组索引,无法定位到嵌套字段。PartnerClaimType="value":直接提取数组会导致声明类型不匹配(dateTime vs JSON数组),因此报错。PartnerClaimType="lastPasswordChangeDateTime":该字段不在JSON根节点,而是嵌套在value数组的对象中,所以无法找到对应值。
内容的提问来源于stack exchange,提问作者myself
相关产品推荐
相关产品推荐

