0
votes

I am attempting to implement a feature within our platform that will perform a Graph API lookup using an ObjectID to retrieve some additional information about the identity, such as display name. This works and is straightforward for local account identities, but not for federated identities. When a federated user signs in to our application using a custom SAML integration, we store their ObjectID in our database so that we may make these kinds of requests later. But when such a request is made, for a federated user, no results are returned.

In researching this problem, I came across a comment on this stack overflow post (AAD B2C adding / mapping claims from external / delegate Identity Provider?) which states "for each external identity, Azure AD B2C creates a user object in its own directory so that you can store claims that are asserted by the external IdP as well as claims that are asserted by the end user or your own application." This makes sense to me, and I can verify it myself in our development environment through the Azure portal. To be more specific, here's what I can observe when I sign in using a federated AAD user:

  • The ObjectID that’s passed to our system through the ID Token is 3d116a96-e9d6-4f12-8185-907f327dd522. This value is the object ID of my user in the AAD directory, not the B2C directory – it originates as the user.objectid field in the AAD IdP, where it’s mapped into the uid SAML claim, then mapped back into the B2C ObjectID claim in the SAML Technical Profile.
  • When I make a Graph API query for a user with that ObjectID, I get no results. This makes sense, given the previous point.
  • When I look at the B2C Users blade in the Azure portal, I can filter down to “external” users and locate my own. This user has sign-ins logged whenever I sign in to our platform using the AAD IdP, so I know it’s the correct external user entry. This user, however, has an ObjectID of a51ee747-bd73-481f-ac84-fce8cacd3309.
  • When I make a Graph API query for that user, I do get a result. I can even store an extension property on it and then retrieve that property as well.

It seems to me that the key here would be to store that second ObjectID in our database, rather than the first one, so that it may be used later to make Graph API requests for the custom attributes that are stored on that identity. The problem is that I can’t figure out how to access or refer to that second ObjectID within our custom policies.

Any advice would be appreciated.

Update

Rohit Prasad's answer below put on me on the right path, where I eventually found the B2C account linking sample, which was extremely helpful and which I was able to adapt to my own situation. Anyone else who's finding this should be aware that, at the time I'm writing this, that sample is slightly outdated - refer to this issue for more info.

2

2 Answers

0
votes

When user authenticated with external IDP (Azure AD), you are creating the account in Azure AD B2C. When you create the account it generates an objectID which you can pass to next step to process further.

<OutputClaim ClaimTypeReferenceId="objectId" />

The ObjectID which is coming from Azure AD is the attribute which in general save under alternateSecurityID with identityProvider.

<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
</OutputClaimsTransformations>

Here,

oid: Object ID of Azure AD

iss: Issuer of Azure AD

CreateAlternativeSecurityId : Use value of oid and iss and save it to alternatesecurityID.

0
votes

Ensure the objectid claim is being output by your relying party definition:

<RelyingParty>
   <DefaultUserJourney />
   <TechnicalProfile>
      <OutputClaims>
         <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
      </OutputClaims>
   </TechnicalProfile>
</RelyingParty>