How to call Technical Profile only during SignUp for B2C Custom Policies?

Nitish Chauhan 81 Reputation points
2024-07-16T21:02:45.94+00:00

I am using a SignIn SignUp flow for custom policy. I am wanting to call an API to send out email, firstname, lastname only when the user is signing up, not when they are performing a normal sign-in. How do I do this using a Precondition?

Here is a policy from the starter pack that is very similar to mine.
https://github.com/azure-ad-b2c/samples/blob/master/policies/username-signup-or-signin/policy/TrustFrameworkExtensions_Username.xml

I have tried several different preconditions and none do what I want.

Calling this after LocalAccountSignUpWithLogonName results in the technical profile not being ran. I believe that is because at this point the object id now exists. Although I can't call this earlier because then the page would not have collected the information I need.

<Preconditions>
	<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
		<Value>objectId</Value>
		<Action>SkipThisOrchestrationStep</Action>
	</Precondition>
</Preconditions>

I have also tried but this gets called on both sign-in and sign-up.

<Preconditions>
	<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
		<Value>userIdentityProvider</Value>
        <Value>localAccountSigninEmailExchange</Value>
		<Action>SkipThisOrchestrationStep</Action>
	</Precondition>
</Preconditions>

I have also search for every occurrence of Precondition in the samples project and none of them shed any light on how to do this.

There is another question that asks a similar question but got XY problem'd and closed. https://learn.microsoft.com/en-us/answers/questions/767335/how-to-call-rest-api-only-during-signup-inside-azu

Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,907 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
22,067 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  2. Shweta Mathur 29,776 Reputation points Microsoft Employee
    2024-07-18T04:07:12.3+00:00

    Nitish Chauhan,

    I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this! Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others", I'll repost your solution in case you'd like to "Accept" the answer.

    Thank you for sharing your solution on previous post too. It would help others in community looking for similar ask.

    Solution

    Here is how to set up the REST API call from documentation

    <ClaimsProvider>
    			<DisplayName>REST API to send events</DisplayName>
    			<TechnicalProfiles>
    				<TechnicalProfile Id="NameOfYourTechnicalProfileId">
    					<DisplayName>REST API to send events</DisplayName>
    					<Protocol Name="Proprietary" 		Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    					<Metadata>
    						<Item Key="ServiceUrl">{AuthApi}/api/v1/YourEndpoint</Item>
    						<Item Key="AuthenticationType">ApiKeyHeader</Item>
    						<Item Key="SendClaimsIn">Body</Item>
    						<Item Key="AllowInsecureAuthInProduction">false</Item>
    					</Metadata>
    					<CryptographicKeys>
    						<Key Id="API-KEY" StorageReferenceId="ApiKey"/>
    					</CryptographicKeys>
    					<InputClaims>
    						<InputClaim ClaimTypeReferenceId="email"/>
    						<InputClaim ClaimTypeReferenceId="givenName" />
    						<InputClaim ClaimTypeReferenceId="surname" />
    					</InputClaims>
    					<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    				</TechnicalProfile>
    			</TechnicalProfiles>
    </ClaimsProvider>
    

    The solution is here. Much simpler than I thought it would be.

    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
    					<DisplayName>Email signup</DisplayName>
    					<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    					<Metadata>
    						<Item Key="IpAddressClaimReferenceId">IpAddress</Item>
    						<Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
    					</Metadata>
    					<CryptographicKeys>
    						<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
    					</CryptographicKeys>
    					<InputClaims>
    						<InputClaim ClaimTypeReferenceId="email" />
    					</InputClaims>
    					<OutputClaims>
    						<OutputClaim ClaimTypeReferenceId="objectId" />
    						<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
    						<OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
    						<OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
    						<OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
    						<OutputClaim ClaimTypeReferenceId="authenticationSource" />
    						<OutputClaim ClaimTypeReferenceId="newUser" />
    						<!-- Optional claims, to be collected from the user -->
    						<!--<OutputClaim ClaimTypeReferenceId="displayName" />-->
    						<OutputClaim ClaimTypeReferenceId="givenName" Required="true" />
    						<OutputClaim ClaimTypeReferenceId="surName" Required="true" />
    					</OutputClaims>
    					<ValidationTechnicalProfiles>
    						<ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
    <!-- ****************************************************************** -->
    <!-- *******************   ADD HERE     ******************************* -->
    						<ValidationTechnicalProfile ReferenceId="NameOfYourTechnicalProfileId"/>
    <!-- ****************************************************************** -->
    					</ValidationTechnicalProfiles>
    					<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
    				</TechnicalProfile>
    

    While trouble-shooting, I would ensure the InputClaims being sent to API are in your ClaimStateBag which can be seen in the App Insights logs during the orchestration step.

    Also a red herring, using this did not work as a new Orchestration Step after the above. I believe this is because after the previous step the objectId is an output claim and would now exist.

    <Preconditions>
    	<Precondition Type="ClaimsExist" ExecuteActionsIf="true"> 					  
    		<Value>objectId</Value> 
    		<Action>SkipThisOrchestrationStep</Action>
    	</Precondition> 
    </Preconditions>
    
    
    

    Thanks

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.