Last active
January 24, 2024 23:27
-
-
Save rbrayb/40a36c6ed55260b26dd95359997ee604 to your computer and use it in GitHub Desktop.
Another look at account linking in Azure AD B2C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
<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="tenant.onmicrosoft.com" PolicyId="B2C_1A_Link_Azure" PublicPolicyUri="http://tenant.onmicrosoft.com/B2C_1A_Link_Azure"> | |
<BasePolicy> | |
<TenantId>tenant.onmicrosoft.com</TenantId> | |
<PolicyId>B2C_1A_TRUSTFRAMEWORKEXTENSIONS</PolicyId> | |
</BasePolicy> | |
<BuildingBlocks> | |
<ClaimsSchema> | |
<ClaimType Id="userIdentities"> | |
<DisplayName>userIdentities</DisplayName> | |
<DataType>userIdentityCollection</DataType> | |
<UserHelpText>userIdentities</UserHelpText> | |
</ClaimType> | |
<ClaimType Id="issuers"> | |
<DisplayName>issuers</DisplayName> | |
<DataType>stringCollection</DataType> | |
<UserHelpText>User identity providers. This information is received from alternativeSecurityIds</UserHelpText> | |
</ClaimType> | |
<ClaimType Id="issuerToLink"> | |
<DisplayName>issuerToLink</DisplayName> | |
<DataType>string</DataType> | |
<AdminHelpText>issuerToLink</AdminHelpText> | |
<UserHelpText>issuerToLink</UserHelpText> | |
</ClaimType> | |
<ClaimType Id="issuerUserIdToLink"> | |
<DisplayName>issuerUserIdToLink</DisplayName> | |
<DataType>string</DataType> | |
<UserHelpText>issuerUserIdToLink</UserHelpText> | |
</ClaimType> | |
<ClaimType Id="userIdentityToLink"> | |
<DisplayName>userIdentityToLink</DisplayName> | |
<DataType>userIdentity</DataType> | |
<UserHelpText>userIdentityToLink</UserHelpText> | |
</ClaimType> | |
</ClaimsSchema> | |
<ClaimsTransformations> | |
<ClaimsTransformation Id="CreateIssuer" TransformationMethod="CopyClaim"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="identityProvider" TransformationClaimType="inputClaim"/> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="issuerToLink" TransformationClaimType="outputClaim"/> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<ClaimsTransformation Id="CreateIssuerUserId" TransformationMethod="CopyClaim"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="issuerUserId" TransformationClaimType="inputClaim"/> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="issuerUserIdToLink" TransformationClaimType="outputClaim"/> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<ClaimsTransformation Id="CreateUserIdentityToLink" TransformationMethod="CreateUserIdentity"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="issuerUserIdToLink" TransformationClaimType="issuerUserId"/> | |
<InputClaim ClaimTypeReferenceId="issuerToLink" TransformationClaimType="issuer"/> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="userIdentityToLink" TransformationClaimType="userIdentity"/> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<ClaimsTransformation Id="AppendUserIdentityToLink" TransformationMethod="AddItemToUserIdentityCollection"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="userIdentityToLink" TransformationClaimType="item"/> | |
<InputClaim ClaimTypeReferenceId="userIdentities" TransformationClaimType="collection"/> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="userIdentities" TransformationClaimType="collection"/> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- Extracts the list of social identity providers associated with the user --> | |
<ClaimsTransformation Id="ExtractIssuers" TransformationMethod="GetIssuersFromUserIdentityCollectionTransformation"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="userIdentities" TransformationClaimType="userIdentityCollection"/> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="issuers" TransformationClaimType="issuersCollection"/> | |
</OutputClaims> | |
</ClaimsTransformation> | |
</ClaimsTransformations> | |
</BuildingBlocks> | |
<ClaimsProviders> | |
<ClaimsProvider> | |
<Domain>MyB2C.com</Domain> | |
<DisplayName>MyB2C</DisplayName> | |
<TechnicalProfiles> | |
<TechnicalProfile Id="AAD-OpenIdConnect"> | |
<DisplayName>Azure Employee</DisplayName> | |
<Description>Login with your Azure account</Description> | |
<Protocol Name="OpenIdConnect"/> | |
<Metadata> | |
<Item Key="METADATA">https://login.microsoftonline.com/tenant.onmicrosoft.com/v2.0/.well-known/openid-configuration</Item> | |
<Item Key="client_id">12...34</Item> | |
<Item Key="response_types">code</Item> | |
<Item Key="scope">openid profile</Item> | |
<Item Key="response_mode">form_post</Item> | |
<Item Key="HttpBinding">POST</Item> | |
<Item Key="UsePolicyInRedirectUri">false</Item> | |
</Metadata> | |
<CryptographicKeys> | |
<Key Id="client_secret" StorageReferenceId="B2C_1A_AzureSecret"/> | |
</CryptographicKeys> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/> | |
<OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/> | |
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name"/> | |
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name"/> | |
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name"/> | |
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="upn"/> | |
<OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn"/> | |
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true"/> | |
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss"/> | |
</OutputClaims> | |
<OutputClaimsTransformations> | |
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/> | |
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/> | |
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/> | |
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/> | |
</OutputClaimsTransformations> | |
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/> | |
</TechnicalProfile> | |
<TechnicalProfile Id="Add-LinkToUser"> | |
<DisplayName>Link</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> | |
<Metadata> | |
<Item Key="ClaimTypeOnWhichToEnable">issuers</Item> | |
<Item Key="ClaimValueOnWhichToEnable">abc</Item> | |
</Metadata> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="issuerUserIdToLink"/> | |
<OutputClaim ClaimTypeReferenceId="issuerToLink"/> | |
</OutputClaims> | |
<OutputClaimsTransformations> | |
<OutputClaimsTransformation ReferenceId="CreateIssuer"/> | |
<OutputClaimsTransformation ReferenceId="CreateIssuerUserId"/> | |
<OutputClaimsTransformation ReferenceId="CreateUserIdentityToLink"/> | |
<OutputClaimsTransformation ReferenceId="AppendUserIdentityToLink"/> | |
</OutputClaimsTransformations> | |
<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD"/> | |
</TechnicalProfile> | |
<!-- Update the userIdentities to add or remove user identity --> | |
<TechnicalProfile Id="AAD-UserUpdateWithUserIdentities"> | |
<Metadata> | |
<Item Key="api-version">1.6</Item> | |
<Item Key="Operation">Write</Item> | |
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">false</Item> | |
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item> | |
</Metadata> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="objectId" Required="true"/> | |
</InputClaims> | |
<PersistedClaims> | |
<PersistedClaim ClaimTypeReferenceId="objectId"/> | |
<PersistedClaim ClaimTypeReferenceId="userIdentities"/> | |
</PersistedClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="objectId"/> | |
<OutputClaim ClaimTypeReferenceId="userIdentities"/> | |
</OutputClaims> | |
<OutputClaimsTransformations> | |
<OutputClaimsTransformation ReferenceId="ExtractIssuers"/> | |
</OutputClaimsTransformations> | |
<IncludeTechnicalProfile ReferenceId="AAD-Common"/> | |
<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD"/> | |
</TechnicalProfile> | |
<TechnicalProfile Id="AAD-UserReadUsingEmailAddress-ToLink"> | |
<Metadata> | |
<Item Key="Operation">Read</Item> | |
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item> | |
</Metadata> | |
<IncludeInSso>false</IncludeInSso> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" Required="true"/> | |
</InputClaims> | |
<OutputClaims> | |
<!-- Required claims --> | |
<OutputClaim ClaimTypeReferenceId="objectId"/> | |
<!-- Optional claims --> | |
<OutputClaim ClaimTypeReferenceId="userPrincipalName"/> | |
<OutputClaim ClaimTypeReferenceId="displayName"/> | |
<OutputClaim ClaimTypeReferenceId="accountEnabled"/> | |
<OutputClaim ClaimTypeReferenceId="otherMails"/> | |
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress"/> | |
</OutputClaims> | |
<OutputClaimsTransformations> | |
<OutputClaimsTransformation ReferenceId="AssertAccountEnabledIsTrue"/> | |
</OutputClaimsTransformations> | |
<IncludeTechnicalProfile ReferenceId="AAD-Common"/> | |
</TechnicalProfile> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
</ClaimsProviders> | |
<UserJourneys> | |
<UserJourney Id="SUSILink"> | |
<OrchestrationSteps> | |
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin"> | |
<ClaimsProviderSelections> | |
<ClaimsProviderSelection TargetClaimsExchangeId="ToLink"/> | |
<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange"/> | |
</ClaimsProviderSelections> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<!-- Check if the user has selected to sign in using one of the social providers --> | |
<OrchestrationStep Order="2" Type="ClaimsExchange"> | |
<Preconditions> | |
<Precondition Type="ClaimsExist" ExecuteActionsIf="true"> | |
<Value>objectId</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
</Preconditions> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="ToLink" TechnicalProfileReferenceId="AAD-OpenIdConnect"/> | |
<ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<OrchestrationStep Order="3" Type="ClaimsExchange"> | |
<Preconditions> | |
<Precondition Type="ClaimsExist" ExecuteActionsIf="true"> | |
<Value>objectId</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
</Preconditions> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="SelfAsserted-Read" TechnicalProfileReferenceId="AAD-UserReadUsingEmailAddress-ToLink"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<OrchestrationStep Order="4" Type="ClaimsExchange"> | |
<Preconditions> | |
<Precondition Type="ClaimEquals" ExecuteActionsIf="true"> | |
<Value>authenticationSource</Value> | |
<Value>localAccountAuthentication</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
</Preconditions> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="Add-LinkToUser" TechnicalProfileReferenceId="Add-LinkToUser"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<OrchestrationStep Order="5" Type="ClaimsExchange"> | |
<Preconditions> | |
<Precondition Type="ClaimEquals" ExecuteActionsIf="true"> | |
<Value>authenticationSource</Value> | |
<Value>localAccountAuthentication</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
</Preconditions> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="AAD-UserUpdateLink" TechnicalProfileReferenceId="AAD-UserUpdateWithUserIdentities"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer"/> | |
</OrchestrationSteps> | |
<ClientDefinition ReferenceId="DefaultWeb"/> | |
</UserJourney> | |
</UserJourneys> | |
<RelyingParty> | |
<DefaultUserJourney ReferenceId="SUSILink"/> | |
<TechnicalProfile Id="PolicyProfile"> | |
<DisplayName>PolicyProfile</DisplayName> | |
<Protocol Name="OpenIdConnect"/> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="displayName"/> | |
<OutputClaim ClaimTypeReferenceId="givenName"/> | |
<OutputClaim ClaimTypeReferenceId="surname"/> | |
<OutputClaim ClaimTypeReferenceId="email"/> | |
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/> | |
<OutputClaim ClaimTypeReferenceId="identityProvider"/> | |
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}"/> | |
</OutputClaims> | |
<SubjectNamingInfo ClaimType="sub"/> | |
</TechnicalProfile> | |
</RelyingParty> | |
</TrustFrameworkPolicy> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://medium.com/the-new-control-plane/another-look-at-account-linking-in-azure-ad-b2c-ea6462e5736e