So, we currently try to switch from our old legacy system to a new IAM Service. And we have decided for Azure AD B2C. But our old legacy system supports all kinds of usernames, something like: "aAADWWADA223" "Test" "[email protected]" "AWDA@..@23" And its kinda hard for us to actually import them properly. And we have actually decided for a JIT migration with the help of the custom policies (the XML policies). But none of us is actually an "identity pro" as Microsoft calls it. So we are basically going for trial and error and we have made some alright progress so far.
So our idea was to actually hash the "signInName" and actually save the hash + the tentant id as the userPrincipalName and the hash as the userName. So the users can still login via their "old" usernames, but in the background we just use the hashes.
We have implemented a small rest-api that actually hashes the names and migrates the accounts just in time. So we have the signInName in our "InputClaims" going to the rest-api. And we wanted to manipulate it there and send it back as an "OutputClaim".
But as soon as we declare the "signInName" as an OutputClaim, we are not allowed to click "Sign In" anymore. Does anybody have an idea, why?
Here is a code-snippet out of "JIT_Migration_TrustFrameworkExtensions":
<!--Demo: Checks if user exists in the migration table. If yes, validate the credentials and migrate the account -->
<TechnicalProfile Id="REST-UserMigration-LocalAccount-SignIn">
<DisplayName>Migrate user sign-in flow</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
<Metadata>
<Item Key="ServiceUrl">https://api.azurecontainerapps.io/api/identity/hash</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="AllowInsecureAuthInProduction">True</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" Required="true"/>
<InputClaim ClaimTypeReferenceId="password" Required="true"/>
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="userPrincipalName"/>
<OutputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="userName"/>
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop"/>
</TechnicalProfile>
Basically we have tried what I've written in the details of the problem already.
If you want to support identities that contain reserved characters then I'd recommend just encoding the characters, then encoding the username entered by the user within B2C itself.
I can't find anything that details which characters can't be used (the docs page seems to be wrong), so I've only used
:
as we know that's reserved from what you've tried so far.You'd first still make a Graph call to create the user, but with the
:
character encoded - I used URL encoding (%3A
):Then in your sign-in page custom policy, call a claims transformation technical profile as a validation step before your non-interactive sign-in.
This claims transformation technical profile should copy the username your user entered (mine is in the claim
signInUsername
) into an,encodedUsername
claim and then call claims transformations to replace the reserved characters with encoded versions.Claims transformation technical profile
Claims transformations
You should then update your non-interactive sign-in technical profile to use the
username
claim rather than the email your user entered.You'd need to find out all the characters that aren't supported in an identity and add one claims transformation per character, e.g. if
#
also weren't supported (even though it is):Your REST API technical profile should also work equally well using this approach. Instead of calling
Transform-NormaliseUsername
you'd call yourREST-UserMigration-LocalAccount-SignIn
but you need the (only) output claim to beencodedUsername
to make it work using the technical profiles above.