无法将 ValidationTechnicalProfile 获取到有效输入

Unable to get ValidationTechnicalProfile to valid input

我正在尝试在 Azure B2C 自定义策略上设置一次性密码 (OTP) 的使用。我有一组工作 Orchestration 步骤,从 URL 中提供的声明令牌中提取电子邮件,然后将随机生成的代码邮寄到该电子邮件。我知道有“VerifyCode”和“GenerateCode”技术资料可用,但它们依赖于用户首先将电子邮件输入显示字段,我想避免这种情况。

我无法触发 ValidationTechnicalProfile 以便它可以对两个声明值执行 ClaimsTransformation。这些是生成的邮寄给用户的 OTP 以及从 TechnicalProvider 收集的输入,该 TechnicalProvider 使用 SelfAssertedAttributeProvider 显示带有 ContentDefinition.

的输入字段

我的代码基于此 article and also a walkthrough with regard to ValidationTechnicalProfiles

请有人解释为什么 ValidationTechnicalProfile 似乎被跳过或无法工作?

索赔

<ClaimType Id="Otp">
  <DisplayName>One-time password</DisplayName>
  <DataType>string</DataType>
</ClaimType>
<ClaimType Id="VerificationCode">
  <DisplayName>Secondary Verification Code</DisplayName>
  <DataType>string</DataType>
  <UserHelpText>Enter your verification code</UserHelpText>
  <UserInputType>TextBox</UserInputType>
</ClaimType>

编排步骤

<OrchestrationStep Order="4" Type="ClaimsExchange">
   <ClaimsExchanges>
      <ClaimsExchange Id="SelfAsserted-OTP-Exchange" TechnicalProfileReferenceId="SelfAsserted-EnterOTP" />
   </ClaimsExchanges>
</OrchestrationStep>

技术简介

使用 api.page.codeinput 内容定义在输入框中收集 VerificationCode 声明的值。收集后,它应该将 Self-AssertedOTPCompare TechnicalProfile 作为 ValidationTechnicalProfile

<TechnicalProfile Id="SelfAsserted-EnterOTP">
 <DisplayName>Enter OTP</DisplayName>
 <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
 <Metadata>
   <Item Key="ContentDefinitionReferenceId">api.page.codeinput</Item>
   <Item Key="UserMessageIfClaimsTransformationStringsAreNotEqual">Invalid OTP Code</Item>
 </Metadata>
 <OutputClaims>
   <OutputClaim ClaimTypeReferenceId="VerificationCode" Required="true" />
 </OutputClaims>
 <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="Self-AssertedOTPCompare" />
 </ValidationTechnicalProfiles>
</TechnicalProfile>

验证技术简介

执行 AssertSuppliedAndGeneratedOTPAreEqual ClaimsTransformation

<TechnicalProfile Id="Self-AssertedOTPCompare">
  <DisplayName>Returns the result from comparing the generated OTP with the supplied on</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="VerificationCode" />
  </OutputClaims>
  <OutputClaimsTransformations>
    <OutputClaimsTransformation ReferenceId="AssertSuppliedAndGeneratedOTPAreEqual" />
  </OutputClaimsTransformations>
</TechnicalProfile>

声明转换

应该比较两个声明并引发异常以防止用户在代码不同时继续操作。

<ClaimsTransformation Id="AssertSuppliedAndGeneratedOTPAreEqual" TransformationMethod="AssertStringClaimsAreEqual">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="Otp" TransformationClaimType="inputClaim1" />
    <InputClaim ClaimTypeReferenceId="VerificationCode" TransformationClaimType="inputClaim2" />
  </InputClaims>
  <InputParameters>
    <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase" />
  </InputParameters>
</ClaimsTransformation>

使用 AppInsights 记录我认为它达到了技术要求,但控制似乎正在返回到编排。如果我从 SelfAsserted-EnterOTP 技术配置文件中删除 ValidationTechnicalProfiles 部分,流程会在用户输入代码的页面停止。

 {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "RecorderRecord": {
        "Values": [
          {
            "Key": "InitiatingClaimsExchange",
            "Value": {
              "ProtocolType": "Identity Experience Engine API",
              "TargetEntity": "Generate-OTP",
              "TechnicalProfileId": "SelfAsserted-EnterOTP",
              "ProtocolProviderType": "SelfAssertedAttributeProvider"
            }
          }
        ]
      },
      "PredicateResult": "True"
    }
  }, 
  {
    "Kind": "Action",
    "Content": "Web.TPEngine.StateMachineHandlers.SwitchToApiOrchestrationHandler"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true
    }
  },
  {
    "Kind": "Transition",
    "Content": {
      "EventName": "SELFASSERTED",
      "StateName": "AwaitingNextStep"
    }
  },

额外

上面的原始实现导致进程从不显示输入字段以从用户那里收集 OTP - jas-suri-msft 表明这是因为 ValidationTechnicalProvider 不会冒出异常。

如果是这种情况,documentation 似乎是错误的:

The AssertStringClaimsAreEqual claims transformation is always executed from a validation technical profile that is called by a self-asserted technical profile, or a DisplayControl. The UserMessageIfClaimsTransformationStringsAreNotEqual metadata of a self-asserted technical profile controls the error message that is presented to the user.

我尝试按照建议将 ValidationTechnicalProfiles 更改为 OutputClaimsTransformations 节点。

我替换了这个:

 <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="Self-AssertedOTPCompare" />
 </ValidationTechnicalProfiles>

有了这个:

<OutputClaimsTransformations>
  <OutputClaimsTransformation 
 ReferenceId="AssertSuppliedAndGeneratedOTPAreEqual" />
</OutputClaimsTransformations>

这导致 OTP 收集屏幕显示,但如果代码错误,页面不会显示任何错误消息,并且不会继续。尽管在元数据中设置了 UserMessageIfClaimsTransformationStringsAreNotEqual,但输入正确的代码允许步骤继续进行。

那么如何让页面显示异常信息呢?

解决方案

如评论中所述,我无法从 ValidationTechnicalProfile 中删除 OutputClaims,因为该政策不会生效。但是,将 OutputClaim 更改为 DisplayClaim 可以解决问题。

<TechnicalProfile Id="SelfAsserted-EnterOTP">
  <DisplayName>Enter OTP</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ContentDefinitionReferenceId">api.page.codeinput</Item>
    <Item Key="UserMessageIfClaimsTransformationStringsAreNotEqual">Invalid OTP Code</Item>
  </Metadata>
  <DisplayClaims>
    <DisplayClaim ClaimTypeReferenceId="suppliedOTP" Required="true" />
  </DisplayClaims>
  <ValidationTechnicalProfiles>
    <ValidationTechnicalProfile ReferenceId="Self-AssertedOTPCompare" />
  </ValidationTechnicalProfiles>
</TechnicalProfile>

当您从验证技术配置文件部分调用声明转换技术配置文件时,错误不会像直接作为 OutputClaimsTransformation 调用时那样冒出来。所以我怀疑您的观察是,输入的任何代码都有效并继续进行下一步。

相反,直接从 SelfAsserted-EnterOTP 调用 AssertSuppliedAndGeneratedOTPAreEqual 作为 OutputClaimsTransformation