Как в Azure AD B2C связать социальную учетную запись пользователя с уже существующей локальной учетной записью при первом входе в систему из социальной учетной записи?
Как я понял из документации, Azure AD B2C создает новую локальную учетную запись для каждого пользователя, который приходит из социальной учетной записи, такой как GMail/Facebook, во время первого входа (поправьте меня, если я не прав). Однако я хочу перехватить это и связать пользователя с уже существующей (собственной) локальной учетной записью без создания новой локальной учетной записи с помощью пользовательских политик.
2 ответа
Образец Wingtip содержит пример этого потока.
См. Файл проверяющей стороны "B2C_1A_link" и маршрут пользователя "Ссылка" для справки.
Обратите внимание, что эта поездка пользователя предлагает конечному пользователю войти в систему с локальной учетной записью, прежде чем он войдет в систему с социальной учетной записью.
Подробный образец приведен здесь.
Обновление "пользовательских идентификаторов" свяжет социальную учетную запись с локальной учетной записью.
Это может быть достигнуто путем перемещения пользователя, аналогичного приведенному ниже.
<UserJourney Id="AccountLinkage">
<PreserveOriginalAssertion>false</PreserveOriginalAssertion>
<OrchestrationSteps>
<!-- Demo: The following orchestration step is always executed.
Asks user to sign-in with local account (only)-->
<OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections">
<ClaimsProviderSelections>
<ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninEmailExchange" />
</ClaimsProviderSelections>
</OrchestrationStep>
<!-- Demo: Sign-in with local account-->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Demo: After user is sign-in, it reads the user, by user object ID,
from the Azure AD identity store. An error is raised if the user does not exist. -->
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Demo: After user is sign-in, and we have the user object ID.
Now, ask the user to re-sign-in, but this time with
one of the social account. This orchestration step, displays the sign-in with social
account buttons.
Note, You may want to add additional social accounts here-->
<OrchestrationStep Order="4" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections">
<ClaimsProviderSelections>
**<ClaimsProviderSelection TargetClaimsExchangeId="GoogleExchange" />
<ClaimsProviderSelection TargetClaimsExchangeId="AmazonAccountExchange" />**
</ClaimsProviderSelections>
</OrchestrationStep>
<!-- Demo: Run the sign-in with social account, based on user choice (from previous step)
Note, You may want to add additional social accounts here -->
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
**<ClaimsExchange Id="GoogleExchange" TechnicalProfileReferenceId="Google-OAUTH" />
<ClaimsExchange Id="AmazonAccountExchange" TechnicalProfileReferenceId="AmazonAccount-OAuth2" />**
</ClaimsExchanges>
</OrchestrationStep>
<!-- Demo: Updates the social account for a user, identified by the object
identifier for the user, in the Azure AD identity store.
An error is raised if the user does not exist. -->
<OrchestrationStep Order="6" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AAD-UserWriteUsingAlternativeSecurityId-ThrowIfNotExists" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId-ThrowIfNotExists" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Demo: Re-reads the user, by user object Id, from the Azure Active Directory.
An error is raised if the user does not exist. -->
<OrchestrationStep Order="7" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectIdAfter" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Demo: Issues a JWT token to the relying party. -->
<OrchestrationStep Order="8" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
</UserJourney>
Затем создайте политику 'LinkExternalAccount.xml', аналогичную приведенной ниже.
<RelyingParty>
<!-- Demo: This relying party policy executes the `AccountLinkage` user journey.
Please see the B2C_1A_Link_TrustFrameworkExtensions policy for more details -->
<DefaultUserJourney ReferenceId="AccountLinkage" />
<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" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
Как только мы запустим наш Linkexternalaccount.xml, он будет перенаправлен на нашу локальную учетную запись, а после успешной регистрации он запросит выбор IDP и на основе выбранного пользователя будет обновлен атрибут "Идентификационные данные пользователя". Мы можем проверить то же самое, опрашивая пользователя. Пример идентификатора пользователя выглядит следующим образом:
**"userIdentities": [
{
"issuer": "google.com",
"issuerUserId": "MTA5MjA5ODQwNzAyNjc3NTEzMzM5"
}**