In our system we’ve added Azure AD Identity Provider to a canned SignInUp user flow and it is working. Now we want to use the Home Realm Discovery custom policy but it is working very differently. (HRD: https://github.com/azure-ad-b2c/samples/blob/master/policies/default-home-realm-discovery/readme.md)
With canned user flows, the Azure AD requires users to signup and a “shadow” user record is created in B2C and that user’s B2C objectId is returned in the claims. The custom policy flow apparently does not require signup for internal users, instead returning the AD objectId instead of the B2C objectId.
We like that internal users don’t have to signup but we have not gotten the custom policies to return all the same claims that the canned user flows did. So, assuming we don’t need to make internal users sign-up, can you tell me what I’ve done wrong in our HRD policy that is causing the missing “emails” claim?
In our HRD custom policy’s AAD-OIDC technical profile, I have these output claims:
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="AADOIDCIDP" AlwaysUseDefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
<OutputClaim ClaimTypeReferenceId="newUser" />
<OutputClaim ClaimTypeReferenceId="upnUserName" PartnerClaimType="upn"/>
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="signInNames.emailAddress"/>
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" />
<OutputClaim ClaimTypeReferenceId="otherMails" PartnerClaimType="otherMails" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateOtherMailsFromEmail" />
<OutputClaimsTransformation ReferenceId="CreateOtherMailsFromSignInNames" />
</OutputClaimsTransformations>
I added these transformations to (hopefully) populate the emails string collection:
<ClaimsTransformation Id="CreateOtherMailsFromEmail" TransformationMethod="AddItemToStringCollection">
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" TransformationClaimType="item" />
<InputClaim ClaimTypeReferenceId="otherMails" TransformationClaimType="collection" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="otherMails" TransformationClaimType="collection" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="CreateOtherMailsFromSignInNames" TransformationMethod="AddItemToStringCollection">
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInNames.emailAddress" TransformationClaimType="item" />
<InputClaim ClaimTypeReferenceId="otherMails" TransformationClaimType="collection" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="otherMails" TransformationClaimType="collection" />
</OutputClaims>
</ClaimsTransformation>
In my RP section, I have these output claims:
<RelyingParty>
<DefaultUserJourney ReferenceId="SignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surName" />
<OutputClaim ClaimTypeReferenceId="newUser" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
<OutputClaim ClaimTypeReferenceId="identityProvider" />
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="identityProviders" />
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
<OutputClaim ClaimTypeReferenceId="otherMails" PartnerClaimType="emails" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="trustFrameworkPolicy" Required="true" DefaultValue="{policy}" PartnerClaimType="tfp" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
Unfortunately when I test at jwt.ms, I’m not seeing this decoded token:
{
"alg": "RS256",
"kid": "stuff",
"typ": "JWT"
}.{
"exp": 1722264175,
"nbf": 1722260575,
"ver": "1.0",
"iss": "https://tenant.b2clogin.com/issuerguid/v2.0/",
"sub": "objected from azure AD",
"aud": "audience guid",
"nonce": "defaultNonce",
"iat": 1722260575,
"auth_time": 1722260575,
"idp": "AADOIDCIDP",
"oid": "objected from azure AD",
"tid": "tenant guid",
"tfp": "B2C_1A_HRD_SIGNIN_ONLY"
}.[Signature]
Ideas?
USA is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.