Last active
January 30, 2025 20:56
-
-
Save rbrayb/ad40c9e563615a40e941e05dce53c608 to your computer and use it in GitHub Desktop.
Using the TOTP MFA method in Azure AD B2C with an authenticator application
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" | |
TenantId="tenant.onmicrosoft.com" | |
PolicyId="B2C_1A_Demo_SignUp_SignIn_Create_TOTP" | |
PublicPolicyUri="http://tenant.onmicrosoft.com/B2C_1A_Demo_SignUp_SignIn_Create_TOTP"> | |
<BasePolicy> | |
<TenantId>tenant.onmicrosoft.com</TenantId> | |
<PolicyId>B2C_1A_Demo_TrustFrameworkExtensions_Create_TOTP</PolicyId> | |
</BasePolicy> | |
<RelyingParty> | |
<DefaultUserJourney ReferenceId="SignUpOrSignInCreateTOTP" /> | |
<TechnicalProfile Id="PolicyProfile"> | |
<DisplayName>PolicyProfile</DisplayName> | |
<Protocol Name="OpenIdConnect" /> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="displayName" /> | |
<OutputClaim ClaimTypeReferenceId="givenName" /> | |
<OutputClaim ClaimTypeReferenceId="surname" /> | |
<OutputClaim ClaimTypeReferenceId="email" /> | |
<OutputClaim ClaimTypeReferenceId="totpIdentifier" /> | |
<OutputClaim ClaimTypeReferenceId="numberOfAvailableDevices" /> | |
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" /> | |
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" /> | |
</OutputClaims> | |
<SubjectNamingInfo ClaimType="sub" /> | |
</TechnicalProfile> | |
</RelyingParty> | |
</TrustFrameworkPolicy> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:xsd="http://www.w3.org/2001/XMLSchema" | |
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="tenant.onmicrosoft.com" PolicyId="B2C_1A_Demo_TrustFrameworkExtensions_Create_TOTP" PublicPolicyUri="http://tenant.onmicrosoft.com/B2C_1A_Demo_TrustFrameworkExtensions_Create_TOTP"> | |
<BasePolicy> | |
<TenantId>tenant.onmicrosoft.com</TenantId> | |
<PolicyId>B2C_1A_TrustFrameworkExtensions_DC</PolicyId> | |
</BasePolicy> | |
<BuildingBlocks> | |
<ClaimsSchema> | |
<ClaimType Id="totpIdentifier"> | |
<DisplayName>UserId, Phone number or Email which can present the user's identity</DisplayName> | |
<DataType>string</DataType> | |
<AdminHelpText>UserId, Phone number or Email which can be used to create QR code identity.</AdminHelpText> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
<ClaimType Id="numberOfAvailableDevices"> | |
<DisplayName>Number of available devices:</DisplayName> | |
<DataType>string</DataType> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
<ClaimType Id="QrCodeScanInstruction"> | |
<DisplayName>Once you've downloaded the Authenticator app, you can use any of the methods below to continue with enrollment.</DisplayName> | |
<DataType>string</DataType> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
<ClaimType Id="QrCodeVerifyInstruction"> | |
<DisplayName>Enter the verification code from your authenticator app.</DisplayName> | |
<DataType>string</DataType> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
<ClaimType Id="qrCodeContent"> | |
<DisplayName>QR Code Text</DisplayName> | |
<DataType>string</DataType> | |
<UserHelpText>QR code text</UserHelpText> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
<ClaimType Id="secretKey"> | |
<DisplayName>If you cant't scan the image, enter the Secret Key:</DisplayName> | |
<DataType>string</DataType> | |
<UserHelpText>QR code secret</UserHelpText> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
<ClaimType Id="otpCode"> | |
<DisplayName>Enter your code</DisplayName> | |
<DataType>string</DataType> | |
<UserHelpText>Enter the 6-digit verification code generated by the the Authenticator app in the box</UserHelpText> | |
<UserInputType>TextBox</UserInputType> | |
<Restriction> | |
<Pattern RegularExpression="^[0-9]{6}$" HelpText="Enter the 6-digit verification code generated by the the Authenticator app in the box" /> | |
</Restriction> | |
</ClaimType> | |
<ClaimType Id="uriLabel"> | |
<DisplayName>Uri Label</DisplayName> | |
<DataType>string</DataType> | |
</ClaimType> | |
<ClaimType Id="issuer"> | |
<DisplayName>Issuer</DisplayName> | |
<DataType>string</DataType> | |
</ClaimType> | |
<!--End of TOTP Claims--> | |
</ClaimsSchema> | |
<ClaimsTransformations> | |
<!-- Create a TOPT secret key--> | |
<ClaimsTransformation Id="CreateSecret" TransformationMethod="CreateOtpSecret"> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="secretKey" TransformationClaimType="outputClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- Create the TOTP issuer name. The issuer name is your tenant name, such as "Contoso demo" --> | |
<ClaimsTransformation Id="CreateIssuer" TransformationMethod="CreateStringClaim"> | |
<InputParameters> | |
<InputParameter Id="value" DataType="string" Value="{AuthenticatorIssuer}" /> | |
</InputParameters> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="issuer" TransformationClaimType="createdClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- Create the TOTP URI label. The label is a combination of the totpIdentifier and the issuer name: | |
For example, Contoso demo:[email protected]> | |
<ClaimsTransformation Id="CreateUriLabel" TransformationMethod="FormatStringMultipleClaims"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="issuer" TransformationClaimType="inputClaim1" /> | |
<InputClaim ClaimTypeReferenceId="totpIdentifier" TransformationClaimType="inputClaim2" /> | |
</InputClaims> | |
<InputParameters> | |
<InputParameter Id="stringFormat" DataType="string" Value="{0}:{1}" /> | |
</InputParameters> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="uriLabel" TransformationClaimType="outputClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- Create the TOTP URI. The label is a combination of the CreateUriLabel and the secret key: | |
For example, otpauth://totp/Contoso%20demo:[email protected]?secret=fay2lj7ynpntjgqa&issuer=Contoso+demo | |
This URI is later converted into a QR code that is presented to the user--> | |
<ClaimsTransformation Id="CreateUriString" TransformationMethod="BuildUri"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="uriLabel" TransformationClaimType="path" /> | |
<InputClaim ClaimTypeReferenceId="secretKey" TransformationClaimType="query.secret" /> | |
</InputClaims> | |
<InputParameters> | |
<InputParameter Id="scheme" DataType="string" Value="otpauth" /> | |
<InputParameter Id="host" DataType="string" Value="totp" /> | |
<InputParameter Id="query.issuer" DataType="string" Value="{AuthenticatorIssuer}" /> | |
</InputParameters> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="qrCodeContent" TransformationClaimType="outputClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- Copy the signInName to the totpIdentifier --> | |
<ClaimsTransformation Id="SignInNameToTotpIdentifier" TransformationMethod="CopyClaim"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="signInName" TransformationClaimType="inputClaim" /> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="totpIdentifier" TransformationClaimType="outputClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- end of TOTP Claims Transforms--> | |
</ClaimsTransformations> | |
<ContentDefinitions> | |
<ContentDefinition Id="api.selfasserted.totp"> | |
<LoadUri>~/tenant/templates/AzureBlue/selfAsserted.cshtml</LoadUri> | |
<RecoveryUri>~/common/default_page_error.html</RecoveryUri> | |
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.9</DataUri> | |
<Metadata> | |
<Item Key="DisplayName">Collect information from user page</Item> | |
</Metadata> | |
<LocalizedResourcesReferences> | |
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.selfasserted.totp.en" /> | |
</LocalizedResourcesReferences> | |
</ContentDefinition> | |
</ContentDefinitions> | |
<Localization> | |
<!-- TOTP localized strings (English) --> | |
<LocalizedResources Id="api.selfasserted.totp.en"> | |
<LocalizedStrings> | |
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorAppIconControl" StringId="title_text">Download the Microsoft Authenticator using the download links for iOS and Android or use any other authenticator app of your choice.</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorAppIconControl" StringId="instruction_text">Once you've downloaded the Authenticator app, you can use any of the methods below to continue with enrollment.</LocalizedString> | |
<LocalizedString ElementType="ClaimType" ElementId="QrCodeScanInstruction" StringId="DisplayName">Once you've downloaded the Authenticator app, you can use any of the methods below to continue with enrollment.</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="title_text">Scan the QR code</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="info_msg">You can download the Microsoft Authenticator app or use any other authenticator app of your choice.</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="totpQrCodeControl" StringId="link_text">Can't scan? Try this</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="title_text">Enter the account details manually</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="account_name">Account Name:</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="display_prefix">Secret</LocalizedString> | |
<LocalizedString ElementType="DisplayControl" ElementId="authenticatorInfoControl" StringId="collapse_text">Still having trouble?</LocalizedString> | |
<!-- Verification --> | |
<LocalizedString ElementType="ClaimType" ElementId="QrCodeVerifyInstruction" StringId="DisplayName">Enter the verification code from your authenticator app.</LocalizedString> | |
<LocalizedString ElementType="ClaimType" ElementId="otpCode" StringId="DisplayName">Enter your code.</LocalizedString> | |
<!-- <LocalizedString ElementType="UxElement" StringId="button_continue">Verify</LocalizedString> --> | |
</LocalizedStrings> | |
</LocalizedResources> | |
</Localization> | |
<DisplayControls> | |
<!-- Render the authenticator apps icon. --> | |
<DisplayControl Id="authenticatorAppIconControl" UserInterfaceControlType="AuthenticatorAppIconControl" /> | |
<!-- Render the QR code. It takes the URI (qrCodeContent) input claim and renders it as a QR code--> | |
<DisplayControl Id="totpQrCodeControl" UserInterfaceControlType="QrCodeControl"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="qrCodeContent" /> | |
</InputClaims> | |
<DisplayClaims> | |
<DisplayClaim ClaimTypeReferenceId="qrCodeContent" ControlClaimType="QrCodeContent" /> | |
</DisplayClaims> | |
</DisplayControl> | |
<!-- Render the TOTP information. It takes the totpIdentifier and the secretKey input claims and renders as a plan text--> | |
<DisplayControl Id="authenticatorInfoControl" UserInterfaceControlType="AuthenticatorInfoControl"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="totpIdentifier" /> | |
<InputClaim ClaimTypeReferenceId="secretKey" /> | |
</InputClaims> | |
<DisplayClaims> | |
<DisplayClaim ClaimTypeReferenceId="totpIdentifier" /> | |
<DisplayClaim ClaimTypeReferenceId="secretKey" /> | |
</DisplayClaims> | |
</DisplayControl> | |
</DisplayControls> | |
<!--End of TOTP contols--> | |
</BuildingBlocks> | |
<ClaimsProviders> | |
<!--Start TOTP--> | |
<ClaimsProvider> | |
<DisplayName>TOTP</DisplayName> | |
<TechnicalProfiles> | |
<!-- Begin the TOTP verification process. | |
This technical profile is called right before the AzureMfa-VerifyOTP technical profile--> | |
<TechnicalProfile Id="AzureMfa-BeginVerifyOTP"> | |
<DisplayName>Create Device</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureMfaProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> | |
<Metadata> | |
<Item Key="Operation">BeginVerifyOTP</Item> | |
</Metadata> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="secretKey" /> | |
<InputClaim ClaimTypeReferenceId="objectId" /> | |
<InputClaim ClaimTypeReferenceId="userPrincipalName" /> | |
</InputClaims> | |
</TechnicalProfile> | |
<!-- Verify the TOTP verification process. | |
This technical profile is called immediately after the AzureMfa-BeginVerifyOTP technical profile--> | |
<TechnicalProfile Id="AzureMfa-VerifyOTP"> | |
<DisplayName>Verify OTP</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureMfaProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> | |
<Metadata> | |
<Item Key="Operation">VerifyOTP</Item> | |
</Metadata> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="otpCode" /> | |
</InputClaims> | |
</TechnicalProfile> | |
<!-- Check the number of devices available for the user. | |
If the number of available devices is zero it indicates the user hasn't enrolled yet --> | |
<TechnicalProfile Id="AzureMfa-GetAvailableDevices"> | |
<DisplayName>Get Available Devices</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureMfaProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> | |
<Metadata> | |
<Item Key="Operation">GetAvailableDevices</Item> | |
</Metadata> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="userPrincipalName" /> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="numberOfAvailableDevices" /> | |
</OutputClaims> | |
</TechnicalProfile> | |
<!-- TOTP session manager--> | |
<TechnicalProfile Id="SM-MFA-TOTP"> | |
<DisplayName>Session Mananagement Provider</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.DefaultSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> | |
<PersistedClaims> | |
<PersistedClaim ClaimTypeReferenceId="totpIdentifier" /> | |
<PersistedClaim ClaimTypeReferenceId="issuer" /> | |
</PersistedClaims> | |
</TechnicalProfile> | |
<!-- Self-asserted technical profile that asks the user to enroll to the TOTP MFA. The technical profile: | |
1) Creates the TOTP secret | |
2) Sets the issuer name and the URI | |
3) Renders the QR code and the authentication URI | |
--> | |
<TechnicalProfile Id="EnableOTPAuthentication"> | |
<DisplayName>Sign up with Authenticator app</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.totp</Item> | |
<Item Key="language.button_continue">Continue</Item> | |
</Metadata> | |
<CryptographicKeys> | |
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" /> | |
</CryptographicKeys> | |
<InputClaimsTransformations> | |
<InputClaimsTransformation ReferenceId="CreateSecret" /> | |
<InputClaimsTransformation ReferenceId="CreateIssuer" /> | |
<InputClaimsTransformation ReferenceId="CreateUriLabel" /> | |
<InputClaimsTransformation ReferenceId="CreateUriString" /> | |
</InputClaimsTransformations> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="qrCodeContent" /> | |
<InputClaim ClaimTypeReferenceId="secretKey" /> | |
</InputClaims> | |
<DisplayClaims> | |
<DisplayClaim DisplayControlReferenceId="authenticatorAppIconControl" /> | |
<DisplayClaim ClaimTypeReferenceId="QrCodeScanInstruction" /> | |
<DisplayClaim DisplayControlReferenceId="totpQrCodeControl" /> | |
<DisplayClaim DisplayControlReferenceId="authenticatorInfoControl" /> | |
</DisplayClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="objectId" /> | |
<OutputClaim ClaimTypeReferenceId="secretKey" /> | |
</OutputClaims> | |
<UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA-TOTP" /> | |
</TechnicalProfile> | |
<!-- Self-asserted technical profile that verifies the TOTP--> | |
<TechnicalProfile Id="OTPVerification"> | |
<DisplayName>Sign in with Authenticator app</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.totp</Item> | |
<Item Key="language.button_continue">Verify</Item> | |
</Metadata> | |
<CryptographicKeys> | |
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" /> | |
</CryptographicKeys> | |
<InputClaims></InputClaims> | |
<DisplayClaims> | |
<DisplayClaim ClaimTypeReferenceId="QrCodeVerifyInstruction" /> | |
<DisplayClaim ClaimTypeReferenceId="otpCode" Required="true" /> | |
</DisplayClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="objectId" /> | |
<OutputClaim ClaimTypeReferenceId="otpCode" Required="true" /> | |
</OutputClaims> | |
<ValidationTechnicalProfiles> | |
<ValidationTechnicalProfile ReferenceId="AzureMfa-BeginVerifyOTP" /> | |
<ValidationTechnicalProfile ReferenceId="AzureMfa-VerifyOTP" /> | |
</ValidationTechnicalProfiles> | |
<UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA-TOTP" /> | |
</TechnicalProfile> | |
<!-- Copy the SignInName to the totpIdentifier --> | |
<TechnicalProfile Id="CreateTotpIdentifier-SignInName"> | |
<DisplayName>Set Totp Default Values</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="totpIdentifier" /> | |
</OutputClaims> | |
<OutputClaimsTransformations> | |
<OutputClaimsTransformation ReferenceId="SignInNameToTotpIdentifier" /> | |
</OutputClaimsTransformations> | |
</TechnicalProfile> | |
<!--end of TOTP--> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
<ClaimsProvider> | |
<DisplayName>Azure Active Directory</DisplayName> | |
<TechnicalProfiles> | |
<TechnicalProfile Id="AAD-UserReadUsingObjectId"> | |
<OutputClaims> | |
<!-- The userPrincipalName is required for the AzureMfaProtocolProvider technical profiles--> | |
<OutputClaim ClaimTypeReferenceId="userPrincipalName" /> | |
</OutputClaims> | |
</TechnicalProfile> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
<ClaimsProvider> | |
<DisplayName>Local Account</DisplayName> | |
<TechnicalProfiles> | |
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email"> | |
<OutputClaims> | |
<!-- The userPrincipalName is required for the AzureMfaProtocolProvider technical profiles--> | |
<OutputClaim ClaimTypeReferenceId="userPrincipalName" /> | |
</OutputClaims> | |
</TechnicalProfile> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
</ClaimsProviders> | |
<UserJourneys> | |
<UserJourney Id="SignUpOrSignInCreateTOTP"> | |
<OrchestrationSteps> | |
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin"> | |
<ClaimsProviderSelections> | |
<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /> | |
</ClaimsProviderSelections> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" /> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<OrchestrationStep Order="2" Type="ClaimsExchange"> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" /> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<!-- Call the TOTP enrollment sub journey. If user already enrolled the sub journey will not ask the user to enroll --> | |
<OrchestrationStep Order="3" Type="InvokeSubJourney"> | |
<JourneyList> | |
<Candidate SubJourneyReferenceId="TotpFactor-Input" /> | |
</JourneyList> | |
</OrchestrationStep> | |
<OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /> | |
</OrchestrationSteps> | |
</UserJourney> | |
</UserJourneys> | |
<SubJourneys> | |
<!--TOTP subjourneys--> | |
<!-- Set the required claims numberOfAvailableDevices and totpIdentifier--> | |
<SubJourney Id="SetTotpInitialValue" Type="Call"> | |
<OrchestrationSteps> | |
<!-- Get the identifier from local account sign-in name--> | |
<OrchestrationStep Order="1" Type="ClaimsExchange"> | |
<Preconditions> | |
<Precondition Type="ClaimsExist" ExecuteActionsIf="true"> | |
<Value>totpIdentifier</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
<Precondition Type="ClaimsExist" ExecuteActionsIf="false"> | |
<Value>signInName</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
</Preconditions> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="SetTotpIdentifierAsSignInName" TechnicalProfileReferenceId="CreateTotpIdentifier-SignInName" /> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
</OrchestrationSteps> | |
</SubJourney> | |
<!-- TOTP enrollment sub journey--> | |
<SubJourney Id="TotpFactor-Input" Type="Call"> | |
<OrchestrationSteps> | |
<!-- Set the required claims numberOfAvailableDevices and totpIdentifier--> | |
<OrchestrationStep Order="1" Type="InvokeSubJourney"> | |
<JourneyList> | |
<Candidate SubJourneyReferenceId="SetTotpInitialValue" /> | |
</JourneyList> | |
</OrchestrationStep> | |
<!-- If current user is not a new one (this is a sign-in flow, and not sign-up), | |
check the number of available devices. --> | |
<OrchestrationStep Order="2" Type="ClaimsExchange"> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="CheckAvailableDevices" TechnicalProfileReferenceId="AzureMfa-GetAvailableDevices" /> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<!-- If the number of available devices is zero (user hasn't enrolled before), | |
render the TOTP enrollment page to scan the QR code that starts the enrollment process --> | |
<OrchestrationStep Order="3" Type="ClaimsExchange"> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="AuthenticatorForSignUp" TechnicalProfileReferenceId="EnableOTPAuthentication" /> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<!-- If the number of available devices is zero (user hasn't enrolled before), | |
render the TOTP verification page. --> | |
<OrchestrationStep Order="4" Type="ClaimsExchange"> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="AuthenticatorForSignIn" TechnicalProfileReferenceId="OTPVerification" /> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
</OrchestrationSteps> | |
</SubJourney> | |
</SubJourneys> | |
</TrustFrameworkPolicy> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://medium.com/the-new-control-plane/using-the-totp-mfa-method-in-azure-ad-b2c-with-an-authenticator-application-02e5af1e9fb6