Issue with B2C SAML Signup Policy and Send Grid for Custom Branded Emails

Nitish Chauhan 81 Reputation points
2022-12-13T19:56:03.29+00:00

For our marketing site which we have a custom policy with the following changes made from the default custom policies.

  1. SAML Integration
    https://learn.microsoft.com/en-us/azure/active-directory-b2c/saml-service-provider?tabs=windows&pivots=b2c-custom-policy
  2. Split Email Verification
    https://learn.microsoft.com/en-us/answers/questions/753722/azure-ad-b2c-signup-email-verification-as-step-aft.html
  3. Protected Web API calls
  4. Send Grid for Custom Branded Emails
    https://learn.microsoft.com/en-us/azure/active-directory-b2c/custom-email-sendgrid?pivots=b2c-custom-policy

Everything worked up until I added the Send Grid integration. The display controls work properly and send to Send Grid and back, but when I try to verify the code it goes to an error page.

I have logged the traces inside app insights but there is no error printed in the logs. Although this is what we are currently seeing from the front-end.
270241-image.png

I am currently unable to figure out a solution without just turning off the custom branded emails, which is a requirement from the business. My best guess is this is something to do with SAML since this setup works perfectly fine on our other custom policies on the same setup for everything except SAML.

The largest difference I can see between the policies is that the SAML custom policies end with

<OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>

Whereas the others end with

<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

Here is the UserJourney we are using for our failing SAML custom policy.

<UserJourneys>  
	<UserJourney Id="SignUpOrSignIn">  
		<OrchestrationSteps>  

			<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">  
				<ClaimsProviderSelections>  
					<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />  
				</ClaimsProviderSelections>  
				<ClaimsExchanges>  
					<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />  
				</ClaimsExchanges>  
			</OrchestrationStep>  

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

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

			<!-- This step reads any user attributes that we may not have received when in the token. -->  
			<OrchestrationStep Order="4" Type="ClaimsExchange">  
				<ClaimsExchanges>  
					<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />  
				</ClaimsExchanges>  
			</OrchestrationStep>  

			<OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>  

		</OrchestrationSteps>  
		<ClientDefinition ReferenceId="DefaultWeb" />  
	</UserJourney>  

Any and all help appreciated!

Microsoft Security | Microsoft Entra | Microsoft Entra External ID
Microsoft Security | Microsoft Entra | Microsoft Entra ID
{count} votes

3 answers

Sort by: Most helpful
  1. Shweta Mathur 30,296 Reputation points Microsoft Employee Moderator
    2022-12-20T07:59:51.457+00:00

    Hi @Nitish Chauhan ,

    Apologies for delay in response.

    You need to enable DeploymentMode to Development to check the detailed logs in the Application Insights to diagnose PII data.

    As you are facing issue with the SAML issuer token, then there might be scenario that issuer URI has not been setup correctly in Saml2AssertionIssuer Technical profile.

    <Item Key="IssuerUri">https://tenant-name.b2clogin.com/tenant-name.onmicrosoft.com/B2C_1A_signup_signin_SAML</Item>

    Also make sure the referenceid of Cryptographic Keys are exactly same as defined in policy keys.

    Hope this will help.

    Thanks,
    Shweta

    ---------------------------------------

    Please remember to "Accept Answer" if answer helped you.

    0 comments No comments

  2. Nitish Chauhan 81 Reputation points
    2023-01-04T23:23:23.237+00:00

    Thanks for the response,

    Firstly, I am able to see logs in app insights searching on the correlationId. There is nothing clearly indicating an error in any of the logs.

    I know the IssuerUri and Cryptographic Keys are correct because this all works when I turn off the SendGrid DisplayControl.

    Is there anything I can do to narrow down what could be causing this? Checking App Insight Logs and Chrome Developer Tools is basically as deep as I can go, and currently that isn't showing any issues, except for a 500 on the final call (with no response body).

    To clarify, I also used this documentation to integrate a WordPress Site with B2C using the miniOrange plugin.
    https://plugins.miniorange.com/saml-single-sign-on-sso-wordpress-using-azure-b2c

    We are also using a custom domain, although when I tried changing the IssuerUri to our custom domain it broke other things.
    https://learn.microsoft.com/en-us/azure/active-directory-b2c/custom-domain?pivots=b2c-custom-policy

    Although again, all of this worked properly until I implemented the custom branded emails using Send Grid.

    Only thing I can think of now is that the SendGrid Technical Profiles use this Protocol

    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

    and SAML uses

    <Protocol Name="SAML2"/>

    but this speculation doesn't really help me diagnose any issue. I am resorting to just trial and error at this point because there's no way for me to diagnose the source of the error.

    0 comments No comments

  3. Nitish Chauhan 81 Reputation points
    2023-01-04T23:25:51.997+00:00

    I would also like to add that the Send Grid Implementation used is identical to what we have used on another client application and it works perfectly. I truly believe there is some incompatibility with the SAML implementation and the Send Grid implementation. I have tried my best not to deviate from the documentation as well.

    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.