Reputation: 31
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>
Upvotes: 0
Views: 689
Reputation: 11325
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
Upvotes: 2
Reputation: 46745
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.
Upvotes: 1