Reputation: 964
I have tried to create a custom policy that replicates the behavior of the default passwordReset policy. I have MFA set, and the default policy will require authentication of the mobile phone number (if it is not already authenticated).
My custom passwordReset policy does NOT request validation of the users mobile, and I am not sure how to change it so that it does.
PasswordReset.xml
<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="onmicrosoft.com"
PolicyId="B2C_1A_Branded_MFA_PasswordReset"
PublicPolicyUri="http://onmicrosoft.com/B2C_1A_Branded_MFA_PasswordReset"
TenantObjectId="">
<BasePolicy>
<TenantId>onmicrosoft.com</TenantId>
<PolicyId>B2C_1A_Branded_MFA_SignIn_FrameworkExtensions</PolicyId>
</BasePolicy>
<RelyingParty>
<DefaultUserJourney ReferenceId="PasswordReset" />
<UserJourneyBehaviors>
<SingleSignOn Scope="Tenant" KeepAliveInDays="14" />
<SessionExpiryType>Absolute</SessionExpiryType>
<SessionExpiryInSeconds>1200</SessionExpiryInSeconds>
<ContentDefinitionParameters>
<Parameter Name="branding">{OAUTH-KV:branding}</Parameter>
</ContentDefinitionParameters>
</UserJourneyBehaviors>
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
</TrustFrameworkPolicy>
Here is a link to the all the policy XML files Policy Files
Upvotes: 0
Views: 1680
Reputation: 14654
In the B2C_1A_Branded_MFA_SignIn_TrustFrameworkBase.xml file, you must add more orchestration steps, between the PasswordResetUsingEmailAddressExchange and NewCredentials orchestration steps, to the PasswordReset user journey, as follows:
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PhoneFactor-Verify" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>newPhoneNumberEntered</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserWriteWithObjectId" TechnicalProfileReferenceId="AAD-UserWritePhoneNumberUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
The first orchestration step must load the authentication phone number, if it has already been registered, for the end user. The strongAuthenticationPhoneNumber claim must be added as an output claim to the LocalAccountDiscoveryUsingEmailAddress and AAD-UserReadUsingEmailAddress technical profiles, as follows:
<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" />
</OutputClaims>
</TechnicalProfile>
and:
<TechnicalProfile Id="AAD-UserReadUsingEmailAddress">
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" />
</OutputClaims>
</TechnicalProfile>
The second orchestration steps prompts the end user to either enter a new authentication phone number, if one hasn't already been registered for them, or verify the existing phone number. The PhoneFactor-InputOrVerify technical profile is declared as follows:
<ClaimsProvider>
<DisplayName>PhoneFactor</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="PhoneFactor-InputOrVerify">
<DisplayName>PhoneFactor</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.PhoneFactorProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ContentDefinitionReferenceId">api.phonefactor</Item>
<Item Key="ManualPhoneNumberEntryAllowed">true</Item>
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
</CryptographicKeys>
<InputClaimsTransformations>
<InputClaimsTransformation ReferenceId="CreateUserIdForMFA" />
</InputClaimsTransformations>
<InputClaims>
<InputClaim ClaimTypeReferenceId="userIdForMFA" PartnerClaimType="UserId" />
<InputClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="Verified.strongAuthenticationPhoneNumber" PartnerClaimType="Verified.OfficePhone" />
<OutputClaim ClaimTypeReferenceId="newPhoneNumberEntered" PartnerClaimType="newPhoneNumberEntered" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-MFA" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
See for the SocialAndLocalAccountsWithMFA files for more information about:
The third orchestration steps saves the authentication phone number, if it hasn't already been registered, for the end user. The AAD-UserWritePhoneNumberUsingObjectId technical profile is declared as follows:
<TechnicalProfile Id="AAD-UserWritePhoneNumberUsingObjectId">
<Metadata>
<Item Key="Operation">Write</Item>
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId="objectId" />
<PersistedClaim ClaimTypeReferenceId="Verified.strongAuthenticationPhoneNumber" PartnerClaimType="strongAuthenticationPhoneNumber" />
</PersistedClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
Upvotes: 1