0

my custom policy has custom 2FA verification sent to email during login user journey. I am using DisplayControls together with SessionManagement to send a single 2FA email message during login. However, during token refresh, the 2FA email message is not skipped despite having pre-condition to skip if isActiveMFASession exists. Please help to check out code snippets of the policy if I misunderstand how my custom policy should be created. Thank you!

Claims

<DisplayControl Id="signInEmailVerificationControl" UserInterfaceControlType="VerificationControl">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" />
  </InputClaims>
  <DisplayClaims>
    <DisplayClaim ClaimTypeReferenceId="email" Required="true" />
    <DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" Required="true" />
  </DisplayClaims>
  <Actions>
    <Action Id="SendCode">
      <ValidationClaimsExchange>
        <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="GenerateOtp" />
        <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="SendOtp" />
      </ValidationClaimsExchange>
    </Action>
    <Action Id="VerifyCode">
      <ValidationClaimsExchange>
        <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="VerifyOtp" />
      </ValidationClaimsExchange>
    </Action>
  </Actions>
</DisplayControl>

Technical Profiles

<TechnicalProfile Id="SelfAsserted-Email-2FA">
  <DisplayName>Self Asserted Email 2FA</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.selfasserted</Item>
    <Item Key="setting.showCancelButton">false</Item>
    <!-- OTP validation error messages -->
    <Item Key="UserMessageIfSessionDoesNotExist">You have exceeded the maximum time allowed.</Item>
    <Item Key="UserMessageIfMaxRetryAttempted">You have exceeded the number of retries allowed.</Item>
    <Item Key="UserMessageIfInvalidCode">You have entered the wrong code.</Item>
    <Item Key="UserMessageIfSessionConflict">Cannot verify the code, please try again later.</Item>
  </Metadata>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" />
  </InputClaims>
  <DisplayClaims>
    <DisplayClaim DisplayControlReferenceId="signInEmailVerificationControl" />
  </DisplayClaims>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA" />
</TechnicalProfile>

<TechnicalProfile Id="SM-MFA">
  <DisplayName>MFA Session Management Provider</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.DefaultSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="isActiveMFASession" DefaultValue="true"/>
  </OutputClaims>
</TechnicalProfile>

Orchestration Step

<!--- after Signin step -->
<OrchestrationStep Order="5" Type="ClaimsExchange">
  <Preconditions>
    <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
      <Value>isActiveMFASession</Value>
      <Action>SkipThisOrchestrationStep</Action>
    </Precondition>
  </Preconditions>
  <ClaimsExchanges>
    <ClaimsExchange Id="Email-2FA" TechnicalProfileReferenceId="SelfAsserted-Email-2FA"/>
  </ClaimsExchanges>
</OrchestrationStep>

2 Answers2

0

One thing I noticed is that you are using ClaimEquals but not specifying what the value should be. I think the precondition should be:

<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
  <Value>isActiveMFASession</Value>
  <Value>true</Value>
  <Action>SkipThisOrchestrationStep</Action>
</Precondition>
juunas
  • 54,244
  • 13
  • 113
  • 149
  • Seems like you are right. I switch to *ClaimEquals* to *ClaimExists*. Let me try it out and wait for the refresh token. Thanks for the quick sharing! – Moon Is Cool May 21 '21 at 07:35
0
  1. Add an output claim isActiveMFASession with defaultValue=“true” in SelfAsserted-Email-2FA.

  2. Add a persisted claim isActiveMFASession to SM-MFA. Remove the output claim you have.

  3. Remove precondition in step 5

Jas Suri - MSFT
  • 10,605
  • 2
  • 10
  • 20
  • Thanks for sharing. Do you mind explaining why we need the steps especially the last one (removal of precondition) as I thought it is the main point of skipping the 2FA step during token refresh? – Moon Is Cool May 21 '21 at 08:57
  • Because your technical profile is skipped in general if it’s part of a session management technical profile that already persisted a claim that’s output by the technical profile, so the precondition isn’t even needed. The Session Management is only established if a session is present, ie when you do token refresh, or SSO, as the user must have already done their fresh logon. Just look at how SM-AAD is working in Step 1 of any of the Starter Pack policies. – Jas Suri - MSFT May 21 '21 at 09:12