共用方式為


使用 Azure Active Directory B2C 自定義原則設定社交帳戶的註冊和登入流程

使用 Azure Active Directory B2C 自定義原則 設定註冊和登入流程一文中,我們會使用 Azure Active Directory B2C (Azure AD B2C) 設定本機帳戶的登入流程。

在本文中,我們會新增外部帳戶的登入流程,例如 Facebook 之類的社交帳戶。 在此情況下,Azure AD B2C 可讓使用者使用來自外部社交識別提供者 (IdP) 的認證來登入您的應用程式。

針對本機帳戶,用戶帳戶是使用user屬性唯一識別的。objectId 針對外部 IdP,我們會使用 alternativeSecurityId 使用者屬性,不過 objectId 仍然存在。

必要條件

注意

本文是 Azure Active Directory B2C 操作指南系列中建立和執行您自己的自定義原則的一部分。 建議您從第一篇文章開始此系列。

步驟 1 - 建立 Facebook 應用程式

使用建立 Facebook 應用程式中所述的步驟來取得 Facebook 應用程式識別碼應用程式秘密 略過必要條件和設定註冊並使用Facebook帳戶登入一文中的其餘步驟。

步驟 2 - 建立 Facebook 原則金鑰

使用在 Azure AD B2C 租使用者中建立 Facebook 金鑰儲存原則金鑰中所述的步驟。 略過必要條件和設定註冊並使用Facebook帳戶登入一文中的其餘步驟。

步驟 3 - 使用 Facebook 設定登入

若要設定使用 Facebook 登入,您必須執行下列步驟:

  • 宣告更多宣告
  • 定義更多宣告轉換,以協助處理宣告操作,例如建立 AlternativeSecurityId
  • 設定Facebook宣告提供者
  • 設定 Microsoft Entra 技術配置檔,以讀取和寫入社交帳戶,以及讀取和寫入 Microsoft Entra 資料庫。
  • 設定自我判斷技術配置檔(用於接受使用者的其他輸入或更新使用者詳細數據),以及其內容定義。

步驟 3.1 - 宣告更多宣告

在 檔案中ContosoCustomPolicy.XMLClaimsSchema,找出 區段,然後使用下列程序代碼宣告更多宣告:

    <!--<ClaimsSchema>-->
        ...
        <ClaimType Id="issuerUserId">
            <DisplayName>Username</DisplayName>
            <DataType>string</DataType>
            <UserHelpText/>
            <UserInputType>TextBox</UserInputType>
            <Restriction>
                <Pattern RegularExpression="^[a-zA-Z0-9]+[a-zA-Z0-9_-]*$" HelpText="The username you provided is not valid. It must begin with an alphabet or number and can contain alphabets, numbers and the following symbols: _ -" />
            </Restriction>
        </ClaimType>
        
        <ClaimType Id="identityProvider">
            <DisplayName>Identity Provider</DisplayName>
            <DataType>string</DataType>
            <UserHelpText/>
        </ClaimType>
        
        <ClaimType Id="authenticationSource">
            <DisplayName>AuthenticationSource</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Specifies whether the user was authenticated at Social IDP or local account.</UserHelpText>
        </ClaimType>  
        
        <ClaimType Id="upnUserName">
            <DisplayName>UPN User Name</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>The user name for creating user principal name.</UserHelpText>
        </ClaimType>
        
        <ClaimType Id="alternativeSecurityId">
            <DisplayName>AlternativeSecurityId</DisplayName>
            <DataType>string</DataType>
            <UserHelpText/>
        </ClaimType>
        
        <ClaimType Id="mailNickName">
            <DisplayName>MailNickName</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Your mail nick name as stored in the Azure Active Directory.</UserHelpText>
        </ClaimType>
        
        <ClaimType Id="newUser">
            <DisplayName>User is new or not</DisplayName>
            <DataType>boolean</DataType>
            <UserHelpText/>
        </ClaimType>
    <!--</ClaimsSchema>-->

步驟 3.2 - 定義宣告轉換

在 檔案中 ContosoCustomPolicy.XML ,找出 ClaimsTransformations 元素,並使用下列程式代碼新增宣告轉換:

   <!--<ClaimsTransformations>-->
       ...
       <ClaimsTransformation Id="CreateRandomUPNUserName" TransformationMethod="CreateRandomString">
           <InputParameters>
               <InputParameter Id="randomGeneratorType" DataType="string" Value="GUID" />
           </InputParameters>
           <OutputClaims>
               <OutputClaim ClaimTypeReferenceId="upnUserName" TransformationClaimType="outputClaim" />
           </OutputClaims>
       </ClaimsTransformation>
   
       <ClaimsTransformation Id="CreateAlternativeSecurityId" TransformationMethod="CreateAlternativeSecurityId">
           <InputClaims>
               <InputClaim ClaimTypeReferenceId="issuerUserId" TransformationClaimType="key" />
               <InputClaim ClaimTypeReferenceId="identityProvider" TransformationClaimType="identityProvider" />
           </InputClaims>
           <OutputClaims>
               <OutputClaim ClaimTypeReferenceId="alternativeSecurityId" TransformationClaimType="alternativeSecurityId" />
           </OutputClaims>
       </ClaimsTransformation>
       
       <ClaimsTransformation Id="CreateUserPrincipalName" TransformationMethod="FormatStringClaim">
           <InputClaims>
               <InputClaim ClaimTypeReferenceId="upnUserName" TransformationClaimType="inputClaim" />
           </InputClaims>
           <InputParameters>
               <InputParameter Id="stringFormat" DataType="string" Value="cpim_{0}@{RelyingPartyTenantId}" />
           </InputParameters>
           <OutputClaims>
               <OutputClaim ClaimTypeReferenceId="userPrincipalName" TransformationClaimType="outputClaim" />
           </OutputClaims>
       </ClaimsTransformation>
   <!--</ClaimsTransformations>-->

我們已定義三個宣告轉換,我們用來產生 和 userPrincipalName 宣告的值alternativeSecurityId。 這些 ClaimsTransformations 會在步驟 3.3 的 OAuth2 技術配置檔中叫用。

步驟 3.3 - 設定 Facebook 宣告提供者

若要讓使用者使用 Facebook 帳戶登入,您必須將帳戶定義為 Azure AD B2C 可以透過端點進行通訊的宣告提供者。 您可以將 Facebook 帳戶定義為宣告提供者。

在 檔案中 ContosoCustomPolicy.XML ,找出 ClaimsProviders 元素,使用下列程式代碼新增宣告提供者:

    <!--<ClaimsProviders>-->
        ...
        <ClaimsProvider>
            <!-- The following Domain element allows this profile to be used if the request comes with domain_hint 
                    query string parameter, e.g. domain_hint=facebook.com  -->
            <Domain>facebook.com</Domain>
            <DisplayName>Facebook</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="Facebook-OAUTH">
                <!-- The text in the following DisplayName element is shown to the user on the claims provider 
                        selection screen. -->
                <DisplayName>Facebook</DisplayName>
                <Protocol Name="OAuth2" />
                <Metadata>
                    <Item Key="ProviderName">facebook</Item>
                    <Item Key="authorization_endpoint">https://www.facebook.com/dialog/oauth</Item>
                    <Item Key="AccessTokenEndpoint">https://graph.facebook.com/oauth/access_token</Item>
                    <Item Key="HttpBinding">GET</Item>
                    <Item Key="UsePolicyInRedirectUri">0</Item>                
                    <Item Key="client_id">facebook-app-id</Item>
                    <Item Key="scope">email public_profile</Item>
                    <Item Key="ClaimsEndpoint">https://graph.facebook.com/me?fields=id,first_name,last_name,name,email</Item>
                    <Item Key="AccessTokenResponseFormat">json</Item>
                </Metadata>
                <CryptographicKeys>
                    <Key Id="client_secret" StorageReferenceId="facebook-policy-key" />
                </CryptographicKeys>
                <InputClaims />
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id" />
                    <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="first_name" />
                    <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="last_name" />
                    <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
                    <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
                    <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="facebook.com" AlwaysUseDefaultValue="true" />
                    <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
                </OutputClaims>
                <OutputClaimsTransformations>
                    <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
                    <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
                    <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
                </OutputClaimsTransformations>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    <!--</ClaimsProviders>-->

將:

  • facebook-app-id使用您在步驟 1取得的 Facebook appID 值。
  • facebook-policy-key使用您在步驟 2取得的 Facebook 原則金鑰名稱。

請注意我們在集合的步驟 3.2 OutputClaimsTransformations定義的宣告轉換。

步驟 3.4 - 建立 Microsoft Entra 技術配置檔

就像使用本機帳戶登入一樣,您必須設定 用來連線到 Microsoft Entra 識別符記憶體的 Microsoft Entra 技術設定檔,以儲存或讀取使用者社交帳戶。

  1. 在 檔案中ContosoCustomPolicy.XMLAAD-UserUpdate,找出技術配置檔,然後使用下列程式代碼新增技術配置檔:

        <TechnicalProfile Id="AAD-UserWriteUsingAlternativeSecurityId">
            <DisplayName>Azure Active Directory technical profile for handling social accounts</DisplayName>
            <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureActiveDirectoryProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    
            <Metadata>
                <Item Key="Operation">Write</Item>
                <Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">true</Item>
            </Metadata>        
    
            <CryptographicKeys>
                <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
            </CryptographicKeys>
            <InputClaims>
                <InputClaim ClaimTypeReferenceId="alternativeSecurityId" PartnerClaimType="alternativeSecurityId" Required="true" />
            </InputClaims>
            <PersistedClaims>
                <!-- Required claims -->
                <PersistedClaim ClaimTypeReferenceId="alternativeSecurityId" />
                <PersistedClaim ClaimTypeReferenceId="userPrincipalName" />
                <PersistedClaim ClaimTypeReferenceId="mailNickName" DefaultValue="unknown" />
                <PersistedClaim ClaimTypeReferenceId="displayName" DefaultValue="unknown" />
    
                <!-- Optional claims -->
                <PersistedClaim ClaimTypeReferenceId="givenName" />
                <PersistedClaim ClaimTypeReferenceId="surname" />
            </PersistedClaims>
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="objectId" />
                <OutputClaim ClaimTypeReferenceId="newUser" PartnerClaimType="newClaimsPrincipalCreated" />
            </OutputClaims>
    
        </TechnicalProfile>
    

    我們已新增 Microsoft Entra 技術配置檔 AAD-UserWriteUsingAlternativeSecurityId ,將新的社交帳戶寫入 Microsoft Entra 識別符。

  2. 將B2C_1A_TokenSigningKeyContainer取代為您在設定簽署中建立的令牌簽署密鑰。

  3. 在 檔案中 ContosoCustomPolicy.XML ,使用下列程序代碼,在 AAD-UserWriteUsingAlternativeSecurityId Technical Profile 後面新增另一個 Microsoft Entra 技術配置檔:

       <TechnicalProfile Id="AAD-UserReadUsingAlternativeSecurityId">
           <DisplayName>Azure Active Directory</DisplayName>
           <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureActiveDirectoryProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
           <Metadata>
               <Item Key="Operation">Read</Item>
               <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">false</Item>
           </Metadata>
           <CryptographicKeys>
               <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
               </CryptographicKeys>
           <InputClaims>
               <InputClaim ClaimTypeReferenceId="alternativeSecurityId" PartnerClaimType="alternativeSecurityId" Required="true" />
           </InputClaims>
           <OutputClaims>
               <!-- Required claims -->
               <OutputClaim ClaimTypeReferenceId="objectId" />
    
               <!-- Optional claims -->
               <OutputClaim ClaimTypeReferenceId="userPrincipalName" />
               <OutputClaim ClaimTypeReferenceId="displayName" />
               <OutputClaim ClaimTypeReferenceId="givenName" />
               <OutputClaim ClaimTypeReferenceId="surname" />
           </OutputClaims>
       </TechnicalProfile>
    

    我們已新增 Microsoft Entra 技術配置檔 AAD-UserReadUsingAlternativeSecurityId ,以從 Microsoft Entra 識別符讀取新的社交帳戶。 它會使用 alternativeSecurityId 作為社交帳戶的唯一標識符。

  4. 將B2C_1A_TokenSigningKeyContainer取代為您在設定簽署中建立的令牌簽署密鑰。

步驟 3.5 - 設定內容定義

使用者登入之後,您可以使用自我判斷技術配置檔從他們收集一些資訊。 因此,您必須設定自我判斷技術配置檔的內容定義。

在 檔案中ContosoCustomPolicy.XMLContentDefinitions,找出 元素,然後使用下列程式代碼在集合中ContentDefinitions新增內容定義:

    <ContentDefinition Id="socialAccountsignupContentDefinition">
        <LoadUri>~/tenant/templates/AzureBlue/selfAsserted.cshtml</LoadUri>
        <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
        <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.7</DataUri>
        <Metadata>
            <Item Key="DisplayName">Collect information from user page alongside those from social Idp.</Item>
        </Metadata>
    </ContentDefinition>

我們會在下一個步驟中將此內容定義作為自我判斷技術配置檔中的元數據(步驟 3.6)。

步驟 3.6 - 設定自我判斷技術配置檔

您在此步驟中設定的自我判斷技術配置檔可用來從使用者收集更多資訊,或更新從社交帳戶取得的類似資訊。

在 檔案中ContosoCustomPolicy.XMLClaimsProviders,找出 區段,然後使用下列程式代碼新增宣告提供者:

    <!--<ClaimsProviders>-->
        ...
        <ClaimsProvider>
            <DisplayName>Self Asserted for social sign in</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="SelfAsserted-Social">
                    <DisplayName>Collect more info during social signup</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                      <Item Key="ContentDefinitionReferenceId">socialAccountsignupContentDefinition</Item>
                    </Metadata>
                    <CryptographicKeys>
                      <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
                    </CryptographicKeys>
                    <InputClaims>
                      <!-- These claims ensure that any values retrieved in the previous steps (e.g. from an external IDP) are prefilled. 
                           Note that some of these claims may not have any value, for example, if the external IDP did not provide any of
                           these values, or if the claim did not appear in the OutputClaims section of the IDP.
                           In addition, if a claim is not in the InputClaims section, but it is in the OutputClaims section, then its
                           value will not be prefilled, but the user will still be prompted for it (with an empty value). -->
                      <InputClaim ClaimTypeReferenceId="displayName" />
                      <InputClaim ClaimTypeReferenceId="givenName" />
                      <InputClaim ClaimTypeReferenceId="surname" />
                    </InputClaims>
                    <!---User will be asked to input or update these values-->
                    <DisplayClaims>
                        <DisplayClaim ClaimTypeReferenceId="displayName"/>
                        <DisplayClaim ClaimTypeReferenceId="givenName"/>
                        <DisplayClaim ClaimTypeReferenceId="surname"/>
                    </DisplayClaims>

                    <OutputClaims>
                      <!-- These claims are not shown to the user because their value is obtained through the "ValidationTechnicalProfiles"
                           referenced below, or a default value is assigned to the claim. A claim is only shown to the user to provide a 
                           value if its value cannot be obtained through any other means. -->
                      <OutputClaim ClaimTypeReferenceId="objectId" />
                      <OutputClaim ClaimTypeReferenceId="newUser" />
                      <!---<OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />-->
          
                      <!-- Optional claims. These claims are collected from the user and can be modified. If a claim is to be persisted in the directory after having been 
                           collected from the user, it needs to be added as a PersistedClaim in the ValidationTechnicalProfile referenced below, i.e. 
                           in AAD-UserWriteUsingAlternativeSecurityId. -->
                      <OutputClaim ClaimTypeReferenceId="displayName" />
                      <OutputClaim ClaimTypeReferenceId="givenName" />
                      <OutputClaim ClaimTypeReferenceId="surname" />
                    </OutputClaims>
                    <ValidationTechnicalProfiles>
                      <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
                    </ValidationTechnicalProfiles>
                  </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    <!--</ClaimsProviders>-->

我們新增的宣告提供者包含自我判斷技術配置檔 SelfAsserted-Social。 自我判斷技術配置檔會 AAD-UserWriteUsingAlternativeSecurityId 使用技術配置檔作為驗證技術配置檔。 因此,當用戶選取 [繼續] 按鈕時,AAD-UserWriteUsingAlternativeSecurityId技術配置檔就會執行(請參閱步驟 7 中的螢幕快照)。

此外,請注意,我們已新增內容定義 socialAccountsignupContentDefinition,我們在元數據區段中的步驟 3.5設定。

步驟 4 - 更新使用者旅程圖協調流程步驟

在 檔案中ContosoCustomPolicy.XMLHelloWorldJourney,找出使用者旅程圖,並將所有協調流程步驟取代為下列程式代碼所示的步驟:

    <!--<OrchestrationSteps>-->
        ...
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp">
            <ClaimsProviderSelections>
                <ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" />
            </ClaimsProviderSelections>
        </OrchestrationStep>
    
        <OrchestrationStep Order="2" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="FacebookExchange"
                    TechnicalProfileReferenceId="Facebook-OAUTH" />
            </ClaimsExchanges>
        </OrchestrationStep>
    
        <!-- For social IDP authentication, attempt to find the user account in the
        directory. -->
        <OrchestrationStep Order="3" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId" />
            </ClaimsExchanges>
        </OrchestrationStep>
    
        <!-- Show self-asserted page only if the directory does not have the user account
        already (i.e. we don't have an objectId).  -->
        <OrchestrationStep Order="4" Type="ClaimsExchange">
            <Preconditions>
                <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                    <Value>objectId</Value>
                    <Action>SkipThisOrchestrationStep</Action>
                </Precondition>
            </Preconditions>
            <ClaimsExchanges>
                <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
            </ClaimsExchanges>
        </OrchestrationStep>
    
        <OrchestrationStep Order="5" Type="ClaimsExchange">
            <Preconditions>
                <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                    <Value>objectId</Value>
                    <Action>SkipThisOrchestrationStep</Action>
                </Precondition>
            </Preconditions>
            <ClaimsExchanges>
                <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
    <!--</OrchestrationSteps>-->

在協調流程中,我們已參考技術配置檔,讓用戶能夠使用社交帳戶登入。

自訂原則執行時:

  • 協調流程步驟 1 - 此步驟包含元素 ClaimsProviderSelections ,其中列出使用者可以選擇的可用登入選項。 在此情況下,我們只有一個選項, FacebookExchange因此當原則執行時,系統會將使用者直接帶到步驟 2 中的 Facebook.com,如 屬性所示 TargetClaimsExchangeId

  • 協調流程步驟 2 - Facebook-OAUTH 技術配置檔會執行,因此使用者會被重新導向至 Facebook 以登入。

  • 協調流程步驟 3 - 在步驟 3AAD-UserReadUsingAlternativeSecurityId ,技術配置檔會執行 以嘗試從 Microsoft Entra ID 記憶體讀取使用者社交帳戶。 如果找到社交帳戶, objectId 則會以輸出宣告的形式傳回。

  • 協調流程步驟 4 - 如果使用者尚未存在(objectId 不存在),則執行此步驟。 它會顯示從使用者收集更多資訊的表單,或更新從社交帳戶取得的類似資訊。

  • 協調流程步驟 5 - 如果使用者尚未存在(objectId 不存在),則此步驟會執行,因此 AAD-UserWriteUsingAlternativeSecurityId 技術配置檔會執行 以將社交帳戶寫入 Microsoft Entra 標識符。

  • 協調流程步驟 6 - 最後,步驟 6 元件,並在原則執行結束時傳回 JWT 令牌。

步驟 5 - 更新信賴憑證者輸出宣告

在 檔案中ContosoCustomPolicy.XMLRelyingParty,找出 元素,然後使用下列程式代碼取代所有輸出宣告集合:

    <OutputClaim ClaimTypeReferenceId="displayName" />
    <OutputClaim ClaimTypeReferenceId="givenName" />
    <OutputClaim ClaimTypeReferenceId="surname" />
    <OutputClaim ClaimTypeReferenceId="email" />
    <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
    <OutputClaim ClaimTypeReferenceId="identityProvider" />

我們已將識別提供者 (identityProvider) 新增為輸出宣告,因此它會包含在傳回給信賴憑證者應用程式的 JWT 令牌中。

步驟 6 - 上傳原則

請遵循上傳自定義原則檔案中的步驟來上傳您的原則檔案。 如果您要上傳與入口網站中已有相同名稱的檔案,請確定您已選取 [覆寫自定義原則] ,如果檔案已經存在

步驟 7 - 測試原則

請遵循測試自定義原則中的步驟來測試您的自定義原則。

系統會將您重新導向至Facebook登入頁面。 輸入您的 Facebook 認證,然後選取 [ 登入]。 我們會在設定 Facebook 時直接將您重新導向至 Facebook,因此在我們的協調流程步驟中,因為我們沒有多個登入選項可供選擇。 一般而言,在應用程式中,您會新增按鈕,例如 使用Facebook登入,其選取時會執行原則。

如果這是第一次執行此原則(Microsoft Entra 記憶體中還沒有任何社交帳戶),您會看到如下所示的螢幕快照。 在後續的原則執行中,您不會看到此畫面,因為社交帳戶已存在於 Microsoft Entra 記憶體中。

Screenshot of sign-in flow with social account.

輸入或更新 [顯示名稱]、[指定名稱] 和 [姓氏],然後選取 [繼續] 按鈕。

原則完成執行之後,系統會將您重新導向至 https://jwt.ms,您會看到已譯碼的 JWT 令牌。 看起來類似下列 JWT 令牌代碼段:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "pxLOMWFgP4T..."
}.{
   ...
  "acr": "b2c_1a_contosocustompolicy",
   ...
  "given_name": "Maurice",
  "family_name": "Paulet",
  "name": "Maurice Paulet",
  "email": "maurice.p@contoso.com",
  "idp": "facebook.com"
}.[Signature]

請注意,識別提供者 "idp": "facebook.com"已包含在 JWT 令牌中。

合併的本機與社交登入

在本文中,我們的使用者旅程流程步驟只會參考技術配置檔,讓用戶能夠使用社交帳戶登入。 我們可以修改協調流程步驟,讓使用者使用本機帳戶或社交帳戶登入。 若要這樣做,第一個協調流程步驟的 ClaimsProviderSelections 元素會列出使用者可用的登入選項。

使用下列步驟來新增合併的本機和社交帳戶:

  1. 在 檔案中 ContosoCustomPolicy.XML ,找出 AccountTypeInputCollector 自我判斷技術配置檔,然後使用下列程式代碼在其輸出宣告集合中新增 authenticationSource 宣告:

        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localIdpAuthentication" AlwaysUseDefaultValue="true" />
    
  2. 在 區 UserJourneys 段中, LocalAndSocialSignInAndSignUp 使用下列程式碼新增使用者旅程圖:

        <!--<UserJourneys>-->
            ...
            <UserJourney Id="LocalAndSocialSignInAndSignUp">
                <OrchestrationSteps>
                    <!--Orchestration steps will be added here-->
                </OrchestrationSteps>
            </UserJourney>
        <!--</UserJourneys>-->
    
  3. 在您建立的使用者旅程圖中, LocalAndSocialSignInAndSignUp 使用下列程式碼新增協調流程步驟:

        <!--<UserJourneys>
            ...
            <UserJourney Id="LocalAndSocialSignInAndSignUp">
                <OrchestrationSteps>-->
                <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="SignupOrSigninContentDefinition">
                    <ClaimsProviderSelections>
                      <ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" />
                      <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
                    </ClaimsProviderSelections>
                    <ClaimsExchanges>
                      <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="UserSignInCollector" />
                    </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="FacebookExchange" TechnicalProfileReferenceId="Facebook-OAUTH" />
                        <ClaimsExchange Id="AccountTypeInputCollectorClaimsExchange" TechnicalProfileReferenceId="AccountTypeInputCollector"/>
                    </ClaimsExchanges>
                </OrchestrationStep>
    
                <!--For Local sign in option start-->
    
                <OrchestrationStep Order="3" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                          <Value>accountType</Value>
                          <Value>work</Value>
                          <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>socialIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="GetAccessCodeClaimsExchange" TechnicalProfileReferenceId="AccessCodeInputCollector" />
                    </ClaimsExchanges>
                </OrchestrationStep>
    
                <OrchestrationStep Order="4" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>socialIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="UserInformationCollector" />
                    </ClaimsExchanges>
                </OrchestrationStep>  
    
                <OrchestrationStep Order="5" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>socialIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserReaderExchange" TechnicalProfileReferenceId="AAD-UserRead"/>
                    </ClaimsExchanges>
                </OrchestrationStep>                
                <!--For Local sign in option end-->
    
                <!--For social sign in option start-->
                <!-- For social IDP authentication, attempt to find the user account in the
                directory. -->
                <OrchestrationStep Order="6" Type="ClaimsExchange">
                   <Preconditions>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                        <Value>authenticationSource</Value>
                        <Value>localIdpAuthentication</Value>
                        <Action>SkipThisOrchestrationStep</Action>
                    </Precondition>
                   </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId" />
                    </ClaimsExchanges>
                </OrchestrationStep>
    
                <!-- Show self-asserted page only if the directory does not have the user account
                already (i.e. we do not have an objectId).  -->
                <OrchestrationStep Order="7" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>localIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
                    </ClaimsExchanges>
                </OrchestrationStep>
    
                <OrchestrationStep Order="8" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>localIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
                    </ClaimsExchanges>
                </OrchestrationStep>
                <!--For social sign in option end-->
                <OrchestrationStep Order="9" Type="ClaimsExchange">
                    <ClaimsExchanges>
                    <ClaimsExchange Id="GetMessageClaimsExchange" TechnicalProfileReferenceId="UserInputMessageClaimGenerator"/>
                    </ClaimsExchanges>          
                </OrchestrationStep>
    
                <OrchestrationStep Order="10" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
               <!-- </OrchestrationSteps>
            </UserJourney>
        </UserJourneys>-->
    

    在第一個步驟中,我們會指定使用者在其旅程、本機或社交驗證中選擇的選項。 在後續步驟中,我們會使用前置條件來追蹤使用者挑選的選項,或使用者所在的旅程階段。 例如,我們使用 authenticationSource 宣告來區分本機驗證旅程和社交驗證旅程。

  4. 在 區 RelyingParty 段中,將 DefaultUserJourney 的 ReferenceId 變更 LocalAndSocialSignInAndSignUp

  5. 使用步驟 6 步驟 7 中的 程式來上傳和執行您的原則。 執行原則之後,您會看到類似下列螢幕擷取畫面的畫面。

    A screenshot of combined local and social sign-up or sign-in interface.

    您可以觀察使用者可以使用本機帳戶或社交帳戶註冊或登入。

下一步