Check if a user exists before executing the resource owner flow in Azure B2C

426 Views Asked by At

We are implementing the Resource Owner flow as described in the Microsoft docs. But before executing the Open ID connect call we would like to check if the user already exists or not. If it doesn't we would like to create it (it would only be used for testing purposes). The ResourceOwnerPassword-Oauth2 technical profile is a literal copy paste from the docs

Hower when we write our UserJourney like this:

        <UserJourney Id="SignInSilent" DefaultCpimIssuerTechnicalProfileReferenceId="JwtIssuer">
        <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
        <OrchestrationSteps>
            <OrchestrationStep Order="1" Type="ClaimsExchange">
                <ClaimsExchanges>
                    <ClaimsExchange Id="CheckIfUserExists" TechnicalProfileReferenceId="AAD-UserExists" />
                </ClaimsExchanges>
            </OrchestrationStep>
            <OrchestrationStep Order="2" Type="ClaimsExchange">
                <ClaimsExchanges>
                    <ClaimsExchange Id="ResourceOwnerFlow" TechnicalProfileReferenceId="ResourceOwnerPasswordCredentials-OAUTH2" />
                </ClaimsExchanges>
            </OrchestrationStep>
          </OrchestrationSteps>
        </UserJourney>
        

Here is the AAD-UserExists

<TechnicalProfile Id="AAD-UserExists">
    <Metadata>
        <Item Key="Operation">Read</Item>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">false</Item>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
    </Metadata>
        <IncludeInSso>false</IncludeInSso>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" DefaultValue="{OIDC:Username}" AlwaysUseDefaultValue="true" Required="true" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" DefaultValue="NOTFOUND" />
        </OutputClaims>
        <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AssertObjectIdObjectIdNotFoundAreEqual" />
        </OutputClaimsTransformations>
        <IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>

We get an error in Application Insight with the following error message

 {
"Kind": "FatalException",
"Content": {
  "Time": "8:24 AM",
  "Exception": {
    "Kind": "Handled",
    "HResult": "80004001",
    "Message": "The method or operation is not implemented.",
    "Data": {}
  }
}
1

There are 1 best solutions below

0
rbrayb On

I'm not sure that you can assign a default value to objectID.

A cleaner way would be:

<TechnicalProfile Id="AAD-UserReadUsingEmailAddress-NoError">
    <Metadata>
        <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">false</Item>
    </Metadata>
    <IncludeTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress"/>
</TechnicalProfile>

and then:

<OrchestrationStep Order="2" Type="ClaimsExchange">
    <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
            <Value>objectId</Value>
            <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
    </Preconditions>
    <ClaimsExchanges>
        <ClaimsExchange Id="CreateUser" TechnicalProfileReferenceId="CreateUser"/>
    </ClaimsExchanges>
</OrchestrationStep>