如何在广告b2c自定义策略中添加“ StringCollection”类型的声明

时间:2019-10-29 18:49:44

标签: azure azure-active-directory azure-ad-b2c

我想添加两个“ StringCollection”类型的输出声明, 1.国家(例如:美国,英国等) 2.组(例如:XX,XY,XZ)

用户注册时需要保存此数据,并且需要将其添加到令牌中

我创建了以下声明类型:

<ClaimType Id="extension_countries">
        <DisplayName>Countries</DisplayName>
        <DataType>stringCollection</DataType>
        <UserHelpText>Country list</UserHelpText>
 </ClaimType>

和转换:

<ClaimsTransformation Id="CreateCountriesFromCountry" TransformationMethod="AddItemToStringCollection">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="country" TransformationClaimType="item" />
          <InputClaim ClaimTypeReferenceId="extension_countries" TransformationClaimType="collection" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="extension_countries" TransformationClaimType="collection" />
        </OutputClaims>
</ClaimsTransformation>

当我添加          到RelyingParty的“ OutputClaims”显示错误 “技术资料中的扩展属性'extension_countries'不支持数据类型'StringCollection'”

3 个答案:

答案 0 :(得分:2)

作为一种解决方法,如果您的字符串大小不超过256个字符(我认为这是最大值),则编写自己的REST函数将集合转换为字符串,反之亦然。

答案 1 :(得分:1)

该错误可能是由于AAD Graph API扩展属性的根本限制:https://docs.microsoft.com/en-us/previous-versions/azure/ad/graph/howto/azure-ad-graph-api-directory-schema-extensions#extension-data-types--

可用类型:

  • 二进制
  • 布尔值
  • DateTime
  • 整数
  • LargeInteger
  • 字符串

所以您不能创建一个扩展属性,它是一个字符串集合。

答案 2 :(得分:0)

你出错的地方是试图定义一个声明,该声明将来自读取 AAD 的调用。创建一个新声明,只是不要将 extension_countries 作为输出声明公开。

首先创建一个新的 ClaimType

      <ClaimType Id="Countries">
        <DisplayName>Countries</DisplayName>
        <DataType>stringCollection</DataType> 
        <UserHelpText>A list of countries for user</UserHelpText>
        <!-- ... removed for brevity -->
      </ClaimType>

然后您创建一个声明转换

     <ClaimsTransformation Id="CountriesClaimFromExtensionCountries" TransformationMethod="StringSplit">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="extension_countries" TransformationClaimType="inputClaim" />
        </InputClaims>
        <InputParameters>
        <InputParameter DataType="string" Id="delimiter" Value="," />
          </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="Countries" TransformationClaimType="outputClaim" />
        </OutputClaims>
      </ClaimsTransformation>

在您的用户旅程中,应该有一个步骤是您使用用户的对象 ID 从 AAD 中读取

<!-- NOTE: This is an example step, for your specific use case it maybe different, but whatever the step is that reads from AAD and gets the extension_countries attribute, do it there. 
          in the token. -->
        <OrchestrationStep Order="6" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>socialIdpAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>

更新该技术配置文件以使用您刚刚创建的声明转换。

<!-- The following technical profile is used to read data after user authenticates. -->
        <TechnicalProfile Id="AAD-UserReadUsingObjectId">
          <Metadata>
            <Item Key="Operation">Read</Item>
            <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
          </Metadata>
          <IncludeInSso>false</IncludeInSso>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
          </InputClaims>
          <OutputClaims>
            <!-- Optional claims -->
            <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
            <OutputClaim ClaimTypeReferenceId="displayName" />
            <OutputClaim ClaimTypeReferenceId="otherMails" />
            <OutputClaim ClaimTypeReferenceId="givenName" />
            <OutputClaim ClaimTypeReferenceId="surname" />
            <!-- NOTE: assuming you already added this -->
            <OutputClaim ClaimTypeReferenceId="extension_countries" />
          </OutputClaims>
          <!-- NOTE: This is where you add the reference to the claims tranformation -->
          <OutputClaimsTransformations>
              <OutputClaimsTransformation ReferenceId="CountriesClaimFromExtensionCountries"/>
          </OutputClaimsTransformations>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>

然后在您的依赖方...确保输出声明。

<RelyingParty>
    <TechnicalProfile Id="PolicyProfile">
      <DisplayName>PolicyProfile</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <OutputClaims>
    <!-- NOTE: new output claim, other output claims are omitted for brevity -->    
        <OutputClaim ClaimTypeReferenceId="Countries" />
      </OutputClaims>
      <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
  </RelyingParty>