0

We are using B2C Custom Policies in production and have a requirement that after a certain time elapses (20 minutes + depending on the application) the user is prompted to login with MFA again irrespective of which service the user is logging into. One of our developers stated that we could use the max_age query string parameter to achieve this and I thought to post here to see if anyone has experience in using this with Azure B2C Custom Policies or could recommend another solution? I found this link but not much else https://github.com/MicrosoftDocs/azure-docs/issues/51307

We are currently using the following MFA method in our policies, slightly modified to remove email verification as we don’t require this : https://github.com/azure-ad-b2c/samples/tree/master/policies/mfa-email-or-phone

Edit

Hi @Jas I've had time to look into the solution but had an issue that I hope you could answer.

We've been able to store the last time the user did MFA in the session rather than in an extension attribute. At first we couldn't get the OutputClaimsTransformation "CompareTimetoLastMFATime" to run after the first login however we found removing in the technical profile "MFAReadStoredMFATime" shown in the code below. Could you please let us know why including SM-MFA blocks the claimstransformation from running on subsequent logins? We see that step 16 is run in the logs however no claimstransformation and no CompareTimetoLastMFATime is output therefore the user always skips MFA.

<OrchestrationStep Order="16" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="MFAReadStoredMFATime" TechnicalProfileReferenceId="MFAReadStoredMFATime" />
                    </ClaimsExchanges>
                </OrchestrationStep>

<OrchestrationStep Order="17" Type="ClaimsExchange">
          <Preconditions>
            <!--Sample: If the preferred MFA method is not 'phone' skip this orchestration step-->
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>extension_mfaByPhoneOrEmail</Value>
              <Value>phone</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
              <Value>mfa_required</Value>
              <Value>true</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>MFADoneByFedIdp</Value>
              <Value>True</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>isLastMFATimeGreaterThanWindow</Value>
                            <Value>False</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="PhoneFactor-Verify" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" />
          </ClaimsExchanges>
        </OrchestrationStep>
<TechnicalProfile Id="MFAReadStoredMFATime">
          <DisplayName>Fixt the session username issue</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <InputClaims>
          <InputClaim ClaimTypeReferenceId="LastMFATime" DefaultValue="2018-10-01T15:00:00.0000000Z" />
          </InputClaims>
          <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="isLastMFATimeGreaterThanWindow" />
          </OutputClaims>
            <OutputClaimsTransformations>
                        <OutputClaimsTransformation ReferenceId="CompareTimetoLastMFATime" />
                    </OutputClaimsTransformations>
        </TechnicalProfile>
<ClaimsTransformation Id="CompareTimetoLastMFATime" TransformationMethod="DateTimeComparison">
                <InputClaims>
                    <InputClaim ClaimTypeReferenceId="LastMFATime" TransformationClaimType="firstDateTime" />
                    <InputClaim ClaimTypeReferenceId="systemDateTime" TransformationClaimType="secondDateTime" />
                </InputClaims>
                <InputParameters>
                    <InputParameter Id="operator" DataType="string" Value="earlier than" />
                    <InputParameter Id="timeSpanInSeconds" DataType="int" Value="100" />
                </InputParameters>
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="isLastMFATimeGreaterThanWindow" TransformationClaimType="result" />
                </OutputClaims>
            </ClaimsTransformation>

2 Answers2

1

Something similar. I assume you mean 20-minute gap between logins?

Look in the samples - there are some examples of password reset that show you how to handle the date/time. In particular, there's one for a reset after 90 days so you could do something similar for MFA.

You can use the resolvers to get the query string value.

The main problem we had is that the query string is a string and there is no method to convert to date/time so we had to do that in an API.

Also, see this.

rbrayb
  • 46,440
  • 34
  • 114
  • 174
1

There is a sample here to force mfa after a certian time has surpassed. https://github.com/azure-ad-b2c/samples/tree/master/policies/mfa-absolute-timeout-and-ip-change-trigger

Jas Suri - MSFT
  • 10,605
  • 2
  • 10
  • 20
  • Hi Jas, thank you for the link. I've tested this this and wondered if it would be possible (perhaps more secure) to store the "LastTimeUserDidMFA" in the session rather than in an extension attribute? – Chris Clark Apr 23 '21 at 09:34
  • Its possible yes. Persist it into the session management technical profile thats used in the technical profile where the timing is being evaluated. – Jas Suri - MSFT Apr 23 '21 at 12:16
  • Hi Jas could you have a look at my edit above please, not sure if you were notified. – Chris Clark May 09 '21 at 18:55
  • When you apply SM-MFA to a technical profile, that technical profile will get skipped if SSO is occurring. – Jas Suri - MSFT May 10 '21 at 05:59