Skip to main content


“Just In Time” User Migration Approach in Azure AD B2C

Colorful Background

“Just In Time” User Migration

This is a continuation of our B2C series on consolidating users identities into Azure B2C.  So far we have looked at the benefits on consolidating user accounts into Azure B2C and a brief overview of the Bulk Migration strategy for migrating users from an existing identity provider into Azure B2C.

The Just in Time (JIT) migration flow for migrating users in Azure B2C should be used if plaintext passwords in the old identity provider are not accessible OR if disrupting the system’s users’ experience is not desired.  Examples include situations such as:

  • The password is stored in a one-way encrypted format, such as with a hash function.
  • The password is stored by the legacy identity provider in a way that you can’t access. For example, when the identity provider validates credentials by calling a web service.

The JIT migration flow still requires pre migration of user accounts, but then uses a custom policy to query a REST API (which you create) to set each users’ password at first sign-in.

The JIT migration flow consists of two phases: Pre-Migration Staging and Seamless Migration Credential Set during the authentication flow.

Pre-Migration Staging

The Pre-Migration Staging tasks are essentially identical to the Bulk migration strategy.  This flow begins with a bulk export from the existing identity provider with all clear-text data that is available from the existing provider. All the required user details will be exported from the current legacy identity provider to an .xlsx or .csv or some other delimited file type.

For data that is not exportable from the legacy identity provider (for example, encrypted passwords) the data should be pre-populated with a placeholder value – something like “ToBeUpdated”…

Similarly to before, you should end up with a data file of some format with all user data and this time with placeholder values for any data that is missing.

One last change before uploading the user data into B2C  – after creating the data export,  an admin for the new B2C tenant should navigate to the “User Attributes” menu within the B2C Tenant and select the option to add a new custom attribute:

User Attributes Menu

Create a custom boolean attribute with the name “userMigrationComplete” like shown:

User Migration Custom Boolean Attribute

This boolean attribute will serve as a flag to tell if the user has been fully transferred over to B2C yet – or if the migration is still pending completion.  Add this attribute as a column to the data files with the list of users and placeholder values that were previously exported from the original identity provider.  Default the value to “False”.

With all placeholder values in place and the new boolean attribute in place,  the data file(s) can then be imported to Azure B2C using the Microsoft Graph API like before with the Bulk migration strategy.

Bulk Migration Automation


Seamless Migration Credential Set

After the staging of the data is complete,  the next step is to compose a Custom Policy that will trigger a REST API during the user Sign-In process.

The REST API should be a very straight-forward POST endpoint which accepts the user’s sign-in request payload as an “InputClaim”  object:

Inputclaim Data Model

After parsing the input,  the API should walk through some simple decision logic to decide what to do with the user’s sign-in request.

Decision Data Flow


  1.  The API should parse the incoming request into the InputClaims data model
  2. The API should then use the Microsoft Graph API to read the Azure AD B2C user account corresponding to the email address identified from the InputClaim input data
  3.  After the user’s data has been queried using the Graph API, conditional logic should check whether the account is flagged for migration by evaluating the current value of the custom attribute we added earlier – “userMigrationComplete”.  If the user has not been migrated yet, this value should be false.
  4.  At this point,  the REST API should attempt to proxy the user’s sign-in request to the legacy identity provider with the username and password that were provided in the InputClaim input data – this is to check if the user trying to sign in is a proper user with valid credentials in the old system.
  5.  If the sign-in request proxied to the legacy identity provider fails because the provided password is incorrect or if the user id does not exist,  the REST API should return a friendly error to the user.  This error will be bubbled up through the custom policy and the user’s interactive authentication session will show them the error message.
  6. If the REST API determines the password is correct, and authentication through the legacy identity provider succeeds,  the API should then use the Graph API to write the password to the Azure AD B2C account and change the boolean extension attribute to “True” – indicating that the migration for that user is complete!
  7. The next time that user attempts to sign in,  the boolean extension attribute will already be true, so the REST API should simply return a Http:200 – OK response and continue the sign-in process as normal.

The high-level architecture for this pattern would look something like this:

Seamless Migration High Level Architecture


This implementation pattern for migrating users from a legacy identity provider to B2C is complex with multiple moving parts – but the benefits are that the users will not experience any delays or interruptions to using their platform; the pre-staging of data into B2C can be done while the platform or solution is still running and pointing toward the legacy identity store. After the staging is complete, the platform can be pointed toward Azure B2C as the new identity provider and their existing password will be validated and updated within B2C in real-time as they try to sign in.

Additionally – if the legacy identity provider does not provide all of the required data in an easily accessible clear-text format – then this seamless migration flow is the only possible option that can be used without interrupting the user or forcing them to reset some of their data.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Elijah Weber

Elijah is a technical director at Perficient, specializing in application modernization and cloud technologies. Before Perficient, he led manufacturing and IT technology teams at ExxonMobil, which enabled the company’s best-in-class manufacturing automation, cybersecurity, site survivability, and system architecture. Elijah is based in Tulsa, Oklahoma.

More from this Author

Follow Us