Azure-docs: email claim?

Created on 19 Feb 2020  Â·  21Comments  Â·  Source: MicrosoftDocs/azure-docs

with this instruction, how to get the user object id and email in the token?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

B2subsvc Pri1 active-directorsvc assigned-to-author product-question triaged

All 21 comments

@koo9 Thanks for your feedback! We will investigate and update as appropriate.

@koo9 can you clarify what you're trying to do? It's not clear what you're requesting here.

@FrankAtHexagon I'm trying to get the user object I'd and email claim into the token in a custom policy that use local account sign in. thx

@koo9 Wrong Frank. 😄

The token's "sub" claim is the user objectId. To add the email address, or to be more specific, the sign-in name, add following output claim to the relying part policy.

<OutputClaim ClaimTypeReferenceId="signInName" DefaultValue="" />

Following is the complete relying party policy sample you can use.

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" 
  TenantId="your-tenant.onmicrosoft.com" PolicyId="B2C_1A_signup_signin" 
  PublicPolicyUri="http://your-tenant.onmicrosoft.com/B2C_1A_signup_signin">
  <BasePolicy>
    <TenantId>your-tenant.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
  </BasePolicy>
  <RelyingParty>
    <DefaultUserJourney ReferenceId="SignUpOrSignIn" />
    <TechnicalProfile Id="PolicyProfile">
      <DisplayName>PolicyProfile</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="displayName" />
        <OutputClaim ClaimTypeReferenceId="givenName" />
        <OutputClaim ClaimTypeReferenceId="surname" />
        <OutputClaim ClaimTypeReferenceId="email" />
        <!--The sign-in name-->
        <OutputClaim ClaimTypeReferenceId="signInName" DefaultValue="" />
        <!--The user object id is sends as "sub"-->
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" />
      </OutputClaims>
      <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
  </RelyingParty>
</TrustFrameworkPolicy>

@yoelhor when used the built-in sign up/in user flow, the token show all claims nicely. under setting, the Application Claims can be configured. if check off User's Object ID, the oid will be included in the token.

{
"exp": 1582132923,
"nbf": 1582129323,
"ver": "1.0",
"iss": "https://b2c.b2clogin.com/36d92541-9dfb-4e8c-b5a2-f7e5d1005a3r/v2.0/",
"sub": "c1a8c276-7267-4804-b299-d7144e0b3c40",
"aud": "bfe5d547-fb11-46d2-b3b7-bedaa6c76266",
"nonce": "defaultNonce",
"iat": 1582129323,
"auth_time": 1582129323,
"oid": "c1a8c276-7267-4804-b299-d7144e0b3c40",
"given_name": "kevin",
"family_name": "yu",
"emails": [
"[email protected]"
],
"tfp": "B2C_1_msignupsignin1"
}.[Signature]

With signInName, the email is return, how to get the claim as email instead of signInName? and oid (although sub is the same as oid in this case)

sub might not be the user object id. oid is the issuer user id. which is unique across application. that's the true user object id. with Azure ad as claim provider, the sub and oid is different.

what I am trying to do is get oid and email for from all claim providers.

Dear @koo9,

I'm afraid there is a confusion between Azure AD token to Azure AD B2C token. In Azure AD B2C token the "sub" is always the user object id, unless you explicitly changed the policy. While in Azure AD the "sub" value is immutable and cannot be reassigned or reused. Azure AD "oid" is the user id.

Yoel

@yoelhor how to get the email from the local account signin? thx

If you are working with the LocalAccounts policies from the starter pack like I do, simply replace the following line within the signup_signin policy file:
Remove: <OutputClaim ClaimTypeReferenceId="email" />
Add: <OutputClaim ClaimTypeReferenceId="SignInName" PartnerClaimType="email"/>

/Peter

@pstapf such a life saver! thx!

how about the oid?

Add
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid"/>

As Yoel mentions, the objectid is already in the sub claim.

@JasSuri I have another outputclaim for

<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid" />

when login with azure ad, it gives a different value than sub. but with
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid"/>

it will map oid to object id which is the same as sub. so obviously we can not mapp oid to different value from different provider.

@koo9 Hi Keven, I'm unsure how to proceed on this one. Have your questions been answered to your satisfaction? It looks like your last comment was more of a statement than question, so unsure whether we're OK to close this issue out or you still have outstanding items to be addressed.

Cc: @JasSuri @yoelhor

@mmacy I don't think I am getting a satisfied answer yet. the RP is for using multiple IDPs and each IDP will its own oid so if I want to get a uniform claims in the token, looks like some kind of conditional logic is required and I don't know if I can do that with the xml (it's xaml or xml scipting/programming here)

It is really unclear what the question or goal is. To me it sounds like you want to pass through the ObjectId (or Unique Identifier) from the federated Identity Provider into the Azure AD B2C issued token? Is that right? This is an unusual practice as the application will then not be able to ever correlate that back to its Identity Provider (Azure AD B2C), for example to do Graph API lookups.

The default behavior is to write a stub account that represents the Federated IdPs account into Azure AD B2C. This then generates an ObjectId. This is the objectId that Azure AD B2C issues into the token for federated IdPs. This is exactly the behavior you get from User Flows too.

This is how we obtain a uniform approach, regardless of the incoming objectid from the federated Idp, we normalize this by issuing the respective ObjectId from the Azure AD B2C stub account, such that both local and federated authentications issue a B2C token with an object id from the same source (Azure AD B2C).

@JasSuri that's the goal. oid is what we want for identifying the user in the application. I wonder what the flow will be in this case. for example when using google login, after the user sign up from the first time, how to create a stub account and return the stub account oid instead of the objectid from Google login? thx

for example when using google login, after the user sign up from the first time, how to create a stub account and return the stub account oid instead of the objectid from Google login?

Thats the default behavior. You don't need to do anything. The sub claim contains this objectId.

that's the google id, that's what I am getting. sometimes the IDP does not return object id or the id in a different claim name. in that case, will need to map that id to oid, sub is not always the oid

Here is the complete flow of how every federation works with the examples we have given.

Lets take the case of Google Federation. The google technnical profile has:

        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id" />

This takes the Google id claim from the Google token, and puts it in issuerUserId claim.
B2C then generates an AlternativeSecurityId by combining the identityProvider claim with the issuerUserId claim (Google Id) using a claims transform:

        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />

B2C then writes a stub account using the technical profile AAD-UserWriteUsingAlternativeSecurityId. This creates the stub account in AAD B2C to represent the Google Account. This operation generates an ObjectId claim, and this objectId is of the AAD B2C stub account, nothing to do with Google.

<OutputClaim ClaimTypeReferenceId="objectId" />

Then this stub accounts objectId is the one that is issued in the Token.

So what you are asking for, as far as i can understand, is already happening by default.

It is broken down in detail here.

All identity providers will return some unique Id, that's what you map into the issuerUserId claim, in Googles case its called id. But again, this id is trashed and the sub accounts ObjectId is the one that's always issued into the B2C token by default.

The sub claim will never contain the objectId from Google or any other federation provider due to this, by default.

@JasSuri thx for the explanation. rock on!

that should conclude this question

Was this page helpful?
0 / 5 - 0 ratings

Related issues

spottedmahn picture spottedmahn  Â·  3Comments

jamesgallagher-ie picture jamesgallagher-ie  Â·  3Comments

jharbieh picture jharbieh  Â·  3Comments

JamesDLD picture JamesDLD  Â·  3Comments

bityob picture bityob  Â·  3Comments