Azure AD B2C User Migration: How to Block Legacy User Sign-Up & Handle Secure Password Reset via Custom Policies
Hello. I am dealing with a user migration scenario from a legacy system to Azure AD B2C, some guidance is needed on my end regarding handling sign-up and password reset for migrated users. The migration strategy involves pre-migrating users with a random password and using Just-In-Time (JIT) migration in tandem with that to capture any straggler users.
Concerns have arisen regarding the following:
Handling Sign-Up and Password Reset: Specifically, what should happen if a migrated user forgets their password, or a new user attempts to sign up? Some Azure AD B2C experts suggest blocking sign-ups and password resets for migrated users to ensure they authenticate using legacy credentials. However the concept is a bit foreign to me and I am trying to understand how to incorporate these concepts with the least possible user friction.
Proposed Solution for Sign Up: I have already tried this and horribly failed, but am willing to give it a shot again if someone can give me some confidence on this. I have created a custom api called LocalAccountSignUp, and I am currently using a test Postgres database which is acting as my legacy identity provider. My LocalAccountSIgnUp API is just taking one inputClaim right now in my code and that is signInName, password is not required for signup right now, because essentially when a user is signing up, they will enter their email, get an otp code to their email inbox, and enter that code in on the sign in screen, and once that code is verified, then they can enter the rest of the fields (like display name, given name). This is how the localaccounsignupwithlogonemail technical profile (Microsoft provided) internally works in the custom policy. Now my LocalAccountSignUp API logic, is running a sql query to check against the legacy Postgres database with the signInName inputclaim, and if this input claim (signInName) hits a user profile in the sql database where the user has that email address (signInName), then I return a custom claim called userExistsLegacy = true, otherwise I return userExistsLegacy = False. I went ahead and created a technical profile for my LocalAccountSignUp api in my extensions file and included userExistsLegacy as an output claim in the technical profile. Then what I tried doing was, in the localaccountsignupwithlogonemail technical profile, I tried adding LocalAccountSignUp (my technical profile) as the first validation technical profile. Keep in mind that localaccountsignupwithlogonemail is a very particular technical profile. Originally the only validation technical profile is AAD-UserWriteUsingLogonEmail. But when i add My LocalAccountSignUp as the first validation profile, the sign up screen breaks, and the box to enter email and verify email and enter otp code disappears. Im having trouble understanding how to prevent sign up because of this breaking issue since the custom policies are finnicky. I think I have the right approach with creating this api and returning a custom claim to use in my custom policies, but the actual logic of custom policies to enforce this is correctly, is what I need help on.
Proposed Solution for Password Reset: For the forgot password scenario, when we are doing user migration we still have to be able to verify if this user exists in the legacy identity provider. Only then will we want to migrate them. Now since they will not be signing in with their original credentials, because they don't know their password, we cannot verify them. So what's the solution here? My thought goes to, if they don't know their password, what they would need to do is click on forgot my password. Then the forgot password screen needs to ask them for a phone number, or email address, basically something that they have set up as a backup flow for resetting their password in legacy. And when they enter their phone number or email address (signInName), and they get a OTP and they would need to enter that otp for verification on the forgot password screen, after verifying the code, then the screen would pop up for them to reset their password. When they have entered their password info and click continue, an api call would be made behind the scenes to update the password of the user on the legacy identity provider. Once it does that, the user would sign in with their new signInName (email address) and (new) password and these credentials would again be verified against legacy (normal sign in migration flow), and now the random password on the users b2c profile (since we premigrated users from legacy provider to b2c with a random password) would be updated with their new password they they reset with in the forgot password flow. I know this is extremely complicated, but its because its a user migration, and we need a way to verify if its a legacy user before allowing them to reset their password, so that we can update the password for that user in legacy when they reset via b2c sign in screen, then allowing us to verify the credentials as they try to sign in normally, which will then finally replace the random password on their profile (that we set when we ran pre migration in bulk with random passwords). I know this is alot, but I hope I have given enough details for a picture to be painted as to what im trying to solve. Please clarify if im thinking around the right lines for these scenarios or if i need to do something else, and give a suggestion for how to create this type of logic.
Proposed Solution for Email Reset: This i havent even thought of yet… yikes. But lets say a user doesnt know their password and they forgot their email address. Do we need to think of anything in such scenarios? If a user has a username (not an email address) that they are using, then i assume they can reset it with an email address they used. But if the email address is itself the username what is the way to reset that, or is it not possible to reset the email?
For summary, the key points im asking about are:
- Should the B2C sign-in page block sign-up for legacy users that are being migrated to azure b2c, and have custom logic for password reset ?
What messaging should be displayed for users who attempt to sign up or reset their password under these conditions?
Detailed guidance is requested to determine the best practices for these scenarios in a high-stakes production environment. Thank you in advance for any insights provided.