使用 Mailjet 進行自訂電子郵件驗證

開始之前,請使用此頁面頂端的 [選擇原則類型] 選取器,選擇您要設定的原則類型。 Azure Active Directory B2C 提供兩種方法來定義使用者如何與您的應用程式互動:透過預先定義的使用者流程,或透過完全可設定的自訂原則。 此文章中所需的步驟隨各方法而異。

在 Azure Active Directory B2C (Azure AD B2C) 中使用自訂電子郵件,以將自訂的電子郵件傳送給註冊以使用您應用程式的使用者。 透過使用第三方電子郵件提供者 Mailjet,您可以使用自己的電子郵件範本和「寄件者:」地址及主旨,並且支援當地語系化和自訂的單次密碼 (OTP) 設定。

此功能僅適用於自訂原則。 如需設定步驟,請在前述選取器中選取 [自訂原則]

自訂電子郵件驗證需要使用第三方電子郵件提供者,例如 MailjetSendGridSparkPost、自訂 REST API 或任何 HTTP 型電子郵件提供者 (包括您自己的)。 本文描述如何設定使用 Mailjet 的解決方案。

建立 Mailjet 帳戶

如果您還沒有帳戶,請從設定 Mailjet 帳戶開始 (Azure 客戶可以解除鎖定 6000 封電子郵件,每日限制為 200 封電子郵件)。

  1. 遵循建立 Mailjet 帳戶中的安裝指示。
  2. 若要能夠傳送電子郵件,請註冊並驗證您的寄件者電子郵件地址或網域。
  3. 瀏覽至 API 金鑰管理頁面。 記錄要在稍後步驟中使用的 API 金鑰秘密金鑰。 當建立您的帳戶時,會自動產生這兩個金鑰。

重要

Mailjet 可讓客戶從共用 IP 和 專用 IP 位址傳送電子郵件。 使用專用 IP 位址時,您必須準備 IP 位址適當地建立自己的信譽。 如需相關資訊,請參閱如何準備我的 IP?

建立 Azure AD B2C 原則金鑰

接下來,將 Mailjet API 金鑰儲存在 Azure AD B2C 原則金鑰中,供您的原則參考。

  1. 登入 Azure 入口網站
  2. 如果您有多個租用戶的存取權,請使用頂端功能表中的 [設定] 圖示,從 [目錄 + 訂用帳戶] 功能表切換至您的 Azure AD B2C 租用戶。
  3. 選擇 Azure 入口網站左上角的 [所有服務],然後搜尋並選取 [Azure AD B2C]
  4. 在 [概觀] 頁面上,選取 [Identity Experience Framework]
  5. 選取 [原則金鑰],然後選取 [新增]
  6. 針對 [選項],選擇 [手動]
  7. 輸入原則金鑰的 [名稱]。 例如: MailjetApiKey 。 金鑰名稱前面會自動新增前置詞 B2C_1A_
  8. 在 [祕密] 中,輸入您先前記錄的 Mailjet [API 金鑰]
  9. 針對 [金鑰使用方法] 選取 [簽章]
  10. 選取 建立
  11. 選取 [原則金鑰],然後選取 [新增]
  12. 針對 [選項],選擇 [手動]
  13. 輸入原則金鑰的 [名稱]。 例如: MailjetSecretKey 。 金鑰名稱前面會自動新增前置詞 B2C_1A_
  14. 在 [祕密] 中,輸入您先前記錄的 Mailjet [祕密金鑰]
  15. 針對 [金鑰使用方法] 選取 [簽章]
  16. 選取 建立

建立 Mailjet 範本

建立了 Mailjet 帳戶並將 Mailjet API 金鑰儲存在 Azure AD B2C 原則金鑰中時,請建立 Mailjet 動態交易範本

  1. 在 Mailjet 網站上,開啟 [交易範本] 頁面,然後選取 [建立新範本]

  2. 選取 [以 HTML 對其進行編碼],然後選取 [從頭開始編碼]

  3. 輸入唯一的範本名稱,例如 Verification email,然後選取 [建立]

  4. 在 HTML 編輯器中,貼上下列 HTML 範本,或使用您自己的範本。 {{var:otp:""}}{{var:email:""}} 參數將動態取代為一次性密碼值和使用者電子郵件地址。

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en"><head id="Head1">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Contoso demo account email verification code</title><meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
       <!-- Template B O365 -->
       <style>
           table td {border-collapse:collapse;margin:0;padding:0;}
       </style>
    </head>
    <body dir="ltr" lang="en">
       <table width="100%" cellpadding="0" cellspacing="0" border="0" dir="ltr" lang="en">
            <tr>
               <td valign="top" width="50%"></td>
               <td valign="top">
                  <!-- Email Header -->
                  <table width="640" cellpadding="0" cellspacing="0" border="0" dir="ltr" lang="en" style="border-left:1px solid #e3e3e3;border-right: 1px solid #e3e3e3;">
                   <tr style="background-color: #0072C6;">
                       <td width="1" style="background:#0072C6; border-top:1px solid #e3e3e3;"></td>
                       <td width="24" style="border-top:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;">&nbsp;</td>
                       <td width="310" valign="middle" style="border-top:1px solid #e3e3e3; border-bottom:1px solid #e3e3e3;padding:12px 0;">
                           <h1 style="line-height:20pt;font-family:Segoe UI Light; font-size:18pt; color:#ffffff; font-weight:normal;">
                            <span id="HeaderPlaceholder_UserVerificationEmailHeader"><font color="#FFFFFF">Verify your email address</font></span>
                           </h1>
                       </td>
                       <td width="24" style="border-top: 1px solid #e3e3e3;border-bottom: 1px solid #e3e3e3;">&nbsp;</td>
                   </tr>
                  </table>
                  <!-- Email Content -->
                  <table width="640" cellpadding="0" cellspacing="0" border="0" dir="ltr" lang="en">
                   <tr>
                       <td width="1" style="background:#e3e3e3;"></td>
                       <td width="24">&nbsp;</td>
                       <td id="PageBody" width="640" valign="top" colspan="2" style="border-bottom:1px solid #e3e3e3;padding:10px 0 20px;border-bottom-style:hidden;">
                           <table cellpadding="0" cellspacing="0" border="0">
                               <tr>
                                   <td width="630" style="font-size:10pt; line-height:13pt; color:#000;">
                                       <table cellpadding="0" cellspacing="0" border="0" width="100%" style="" dir="ltr" lang="en">
                                           <tr>
                                               <td>
    
       <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; color:#333;">
           <span id="BodyPlaceholder_UserVerificationEmailBodySentence1">Thanks for verifying your {{var:email:""}} account!</span>
       </div>
       <br>
       <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; color:#333; font-weight: bold">
           <span id="BodyPlaceholder_UserVerificationEmailBodySentence2">Your code is: {{var:otp:""}}</span>
       </div>
       <br>
       <br>
    
                                                   <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; color:#333;">
                                                   Sincerely,
                                                   </div>
                                                   <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; font-style:italic; color:#333;">
                                                       Contoso
                                                   </div>
                                               </td>
                                           </tr>
                                       </table>
                                   </td>
                               </tr>
                           </table>
    
                       </td>
    
                       <td width="1">&nbsp;</td>
                       <td width="1"></td>
                       <td width="1">&nbsp;</td>
                       <td width="1" valign="top"></td>
                       <td width="29">&nbsp;</td>
                       <td width="1" style="background:#e3e3e3;"></td>
                   </tr>
                   <tr>
                       <td width="1" style="background:#e3e3e3; border-bottom:1px solid #e3e3e3;"></td>
                       <td width="24" style="border-bottom:1px solid #e3e3e3;">&nbsp;</td>
                       <td id="PageFooterContainer" width="585" valign="top" colspan="6" style="border-bottom:1px solid #e3e3e3;padding:0px;">
    
                       </td>
    
                       <td width="29" style="border-bottom:1px solid #e3e3e3;">&nbsp;</td>
                       <td width="1" style="background:#e3e3e3; border-bottom:1px solid #e3e3e3;"></td>
                   </tr>
                  </table>
    
               </td>
               <td valign="top" width="50%"></td>
           </tr>
       </table>
    </body>
    </html>
    
  5. 展開左上方的 [編輯主旨]

    1. 針對 [主旨],輸入主旨的預設值。 當 API 未包含 subject 參數時,Mailjet 會使用此值。
    2. 針對 [名稱],輸入您的公司名稱。
    3. 針對 [位址],選取您的電子郵件地址
    4. 選取 [儲存]。
  6. 從右上方選取 [儲存並發佈],然後按一下 [是,發佈變更]

  7. 記錄範本的範本識別碼,此範本是您為了要在後續步驟中使用而建立的。 當您新增宣告轉換時,可以指定此識別碼。

重要

接下來的步驟會顯示如何建置您的自訂原則 XML 檔案。 建議您使用 GitHub 上提供的範例自訂電子郵件驗證自訂原則。 DisplayControl_TrustFrameworkExtensions.xml 會使用 TrustFrameworkExtensions.xml 作為其基礎檔案,因此請務必在您的原則中包含來自 SocialAndLocalAccounts入門套件TrustFrameworkBase.xmlTrustFrameworkLocalization.xmlTrustFrameworkExtensions.xml 檔案。

新增 Azure AD B2C 宣告類型

在您的原則中,將下列宣告類型新增至 <BuildingBlocks> 內的 <ClaimsSchema> 元素。

需要這些宣告類型,才能使用單次密碼 (OTP) 代碼來產生並驗證電子郵件地址。

<!--
<BuildingBlocks>
  <ClaimsSchema> -->
    <ClaimType Id="Otp">
      <DisplayName>Secondary One-time password</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
    <ClaimType Id="emailRequestBody">
      <DisplayName>Mailjet request body</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
    <ClaimType Id="VerificationCode">
      <DisplayName>Secondary Verification Code</DisplayName>
      <DataType>string</DataType>
      <UserHelpText>Enter your email verification code</UserHelpText>
      <UserInputType>TextBox</UserInputType>
    </ClaimType>
  <!-- 
  </ClaimsSchema>
</BuildingBlocks> -->

新增宣告轉換

接下來,您需要宣告轉換來輸出 JSON 字串宣告,此宣告將會是傳送至 Mailjet 的要求主體。

JSON 物件的結構是以 InputParameter 的 ID (採用點標記法) 及 InputClaim 的 TransformationClaimType 來定義。 點標記法中的數字暗指陣列。 值來自於 InputClaim 的值和 InputParameter 的 "Value" 屬性。 如需 JSON 宣告轉換的詳細資訊,請參閱 JSON 宣告轉換

將下列宣告轉換新增至 <BuildingBlocks> 內的 <ClaimsTransformations> 元素。 對宣告轉換 XML 進行下列更新:

  • 使用您稍早在建立 Mailjet 範本中建立的 Mailjet 交易範本識別碼,更新 Messages.0.TemplateID InputParameter 值。
  • 更新 Messages.0.From.Email 位址值。 請使用有效的電子郵件地址,以協助防止驗證電子郵件被標示為垃圾郵件。
  • 使用適合於您組織的主旨行,更新 Messages.0.Subject 主旨行輸入參數的值。
<!-- 
<BuildingBlocks>
  <ClaimsTransformations> -->
    <ClaimsTransformation Id="GenerateEmailRequestBody" TransformationMethod="GenerateJson">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="Messages.0.To.0.Email" />
        <InputClaim ClaimTypeReferenceId="otp" TransformationClaimType="Messages.0.Variables.otp" />
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="Messages.0.Variables.email" />
      </InputClaims>
      <InputParameters>
        <!-- Update the template_id value with the ID of your Mailjet template. -->
        <InputParameter Id="Messages.0.TemplateID" DataType="int" Value="1234567"/>
        <InputParameter Id="Messages.0.TemplateLanguage" DataType="boolean" Value="true"/>

        <!-- Update with an email appropriate for your organization. -->
        <InputParameter Id="Messages.0.From.Email" DataType="string" Value="my_email@mydomain.com"/>

        <!-- Update with a subject line appropriate for your organization. -->
        <InputParameter Id="Messages.0.Subject" DataType="string" Value="Contoso account email verification code"/>
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailRequestBody" TransformationClaimType="outputClaim"/>
      </OutputClaims>
    </ClaimsTransformation>
  <!--
  </ClaimsTransformations>
</BuildingBlocks> -->

新增 DataUri 內容定義

<BuildingBlocks> 內的宣告轉換下方,新增下列 ContentDefinition 以參考 2.1.2 版資料 URI:

<!--
<BuildingBlocks> -->
  <ContentDefinitions>
   <ContentDefinition Id="api.localaccountsignup">
      <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
    </ContentDefinition>
    <ContentDefinition Id="api.localaccountpasswordreset">
      <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
    </ContentDefinition>
  </ContentDefinitions>
<!--
</BuildingBlocks> -->

建立 DisplayControl

搭配使用驗證顯示控制項與傳送給使用者的驗證碼,以驗證電子郵件地址。

此範例顯示控制項會設定為:

  1. 從使用者收集 email 位址宣告類型。

  2. 使用 SendCode 動作,產生 OTP 代碼,並將具有 OTP 代碼的電子郵件傳送給使用者。

    Send verification code email action

  3. 等候使用者提供程式碼已傳送給使用者的 verificationCode 宣告類型。

  4. email 傳回至自我判斷的技術設定檔,而此設定檔具有此顯示控制項的參考。

在內容定義 (仍在 <BuildingBlocks> 內) 下,將類型為 VerificationControl 的下列 DisplayControl 新增至您的原則。

<!--
<BuildingBlocks> -->
  <DisplayControls>
    <DisplayControl Id="emailVerificationControl" UserInterfaceControlType="VerificationControl">
      <DisplayClaims>
        <DisplayClaim ClaimTypeReferenceId="email" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" Required="true" />
      </DisplayClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" />
      </OutputClaims>
      <Actions>
        <Action Id="SendCode">
          <ValidationClaimsExchange>
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="GenerateOtp" />
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="SendOtp" />
          </ValidationClaimsExchange>
        </Action>
        <Action Id="VerifyCode">
          <ValidationClaimsExchange>
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="VerifyOtp" />
          </ValidationClaimsExchange>
        </Action>
      </Actions>
    </DisplayControl>
  </DisplayControls>
<!--
</BuildingBlocks> -->

新增 OTP 技術設定檔

GenerateOtp 技術設定檔會產生電子郵件地址的代碼。 VerifyOtp 技術設定檔會驗證與電子郵件地址相關聯的代碼。 您可以變更格式的設定以及單次密碼的到期時間。 如需 OTP 技術設定檔的詳細資訊,請參閱定義單次密碼技術設定檔

注意

Web.TPEngine.Providers.OneTimePasswordProtocolProvider 通訊協定所產生的 OTP 代碼會連結至瀏覽器工作階段。 這表示使用者可以在不同的瀏覽器工作階段中產生唯一的 OTP 代碼,而每個代碼都適用於其對應的工作階段。 相反地,內建電子郵件提供者所產生的 OTP 代碼與瀏覽器工作階段無關,因此,如果使用者在新的瀏覽器工作階段中產生新的 OTP 代碼,則其會取代先前的 OTP 代碼。

將下列技術設定檔新增至 <ClaimsProviders> 元素。

<!--
<ClaimsProviders> -->
  <ClaimsProvider>
    <DisplayName>One time password technical profiles</DisplayName>
    <TechnicalProfiles>
      <TechnicalProfile Id="GenerateOtp">
        <DisplayName>Generate one time password</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.OneTimePasswordProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="Operation">GenerateCode</Item>
          <Item Key="CodeExpirationInSeconds">600</Item>
          <Item Key="CodeLength">6</Item>
          <Item Key="CharacterSet">0-9</Item>
          <Item Key="NumRetryAttempts">5</Item>
          <Item Key="NumCodeGenerationAttempts">10</Item>
          <Item Key="ReuseSameCode">false</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="identifier" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="otp" PartnerClaimType="otpGenerated" />
        </OutputClaims>
      </TechnicalProfile>

      <TechnicalProfile Id="VerifyOtp">
        <DisplayName>Verify one time password</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.OneTimePasswordProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="Operation">VerifyCode</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="identifier" />
          <InputClaim ClaimTypeReferenceId="verificationCode" PartnerClaimType="otpToVerify" />
        </InputClaims>
      </TechnicalProfile>
     </TechnicalProfiles>
  </ClaimsProvider>
<!--
</ClaimsProviders> -->

新增 REST API 技術設定檔

此 REST API 技術設定檔會產生電子郵件內容 (使用 Mailjet 格式)。 如需 RESTful 技術設定檔的詳細資訊,請參閱定義 RESTful 技術設定檔

如同 OTP 技術設定檔,請將下列技術設定檔新增至 <ClaimsProviders> 元素。

<ClaimsProvider>
  <DisplayName>RestfulProvider</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="sendOtp">
      <DisplayName>Use email API to send the code to the user</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://api.mailjet.com/v3.1/send</Item>
        <Item Key="AuthenticationType">Basic</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="ClaimUsedForRequestPayload">emailRequestBody</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_MailjetApiKey" />
        <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_MailjetSecretKey" />
      </CryptographicKeys>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateEmailRequestBody" />
      </InputClaimsTransformations>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="emailRequestBody" />
      </InputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

建立 DisplayControl 的參考

在最終步驟中,新增所建立 DisplayControl 的參考。 使用下列 XML 程式碼片段,覆寫基礎原則中所設定的現有 LocalAccountSignUpWithLogonEmailLocalAccountDiscoveryUsingEmailAddress 自我判斷技術設定檔。 如果您已使用舊版 Azure AD B2C 原則,則這些技術設定檔會搭配使用 DisplayClaimsDisplayControl 的參考。

如需詳細資訊,請參閱自我判斷技術設定檔DisplayControl

<ClaimsProvider>
  <DisplayName>Local Account</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
      <DisplayClaims>
        <DisplayClaim DisplayControlReferenceId="emailVerificationControl" />
        <DisplayClaim ClaimTypeReferenceId="displayName" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="givenName" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="surName" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="newPassword" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
      </DisplayClaims>
    </TechnicalProfile>
    <TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
      <DisplayClaims>
        <DisplayClaim DisplayControlReferenceId="emailVerificationControl" />
      </DisplayClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

[選擇性] 將您的電子郵件當地語系化

若要將電子郵件當地語系化,您必須將當地語系化的字串傳送至 Mailjet 或您的電子郵件提供者。 例如,您可以將電子郵件主旨、主體、程式碼訊息或電子郵件簽章當地語系化。 若要這樣做,您可以使用 GetLocalizedStringsTransformation 宣告轉換,將當地語系化的字串複製到宣告類型。 產生 JSON 承載的 GenerateEmailRequestBody 宣告轉換會使用輸入宣告,其中包含當地語系化的字串。

  1. 在您的原則中,定義下列字串宣告:subject、message、codeIntro 和 signature。

  2. 定義 GetLocalizedStringsTransformation 宣告轉換,將當地語系化的字串值替代為來自步驟 1 的宣告。

  3. 變更 GenerateEmailRequestBody 宣告轉換,以使用輸入宣告搭配下列 XML 程式碼片段。

  4. 更新您的 Mailjet 範本,以使用動態參數取代將由 Azure AD B2C 當地語系化的所有字串。

    <ClaimsTransformation Id="GetLocalizedStringsForEmail" TransformationMethod="GetLocalizedStringsTransformation">
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="subject" TransformationClaimType="email_subject" />
        <OutputClaim ClaimTypeReferenceId="message" TransformationClaimType="email_message" />
        <OutputClaim ClaimTypeReferenceId="codeIntro" TransformationClaimType="email_code" />
        <OutputClaim ClaimTypeReferenceId="signature" TransformationClaimType="email_signature" />
      </OutputClaims>
    </ClaimsTransformation>
    <ClaimsTransformation Id="GenerateEmailRequestBody" TransformationMethod="GenerateJson">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="Messages.0.To.0.Email" />
        <InputClaim ClaimTypeReferenceId="subject" TransformationClaimType="Messages.0.Subject" />
        <InputClaim ClaimTypeReferenceId="otp" TransformationClaimType="Messages.0.Variables.otp" />
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="Messages.0.Variables.email" />
        <InputClaim ClaimTypeReferenceId="message" TransformationClaimType="Messages.0.Variables.otpmessage" />
        <InputClaim ClaimTypeReferenceId="codeIntro" TransformationClaimType="Messages.0.Variables.otpcodeIntro" />
        <InputClaim ClaimTypeReferenceId="signature" TransformationClaimType="Messages.0.Variables.otpsignature" />
      </InputClaims>
      <InputParameters>
        <!-- Update the template_id value with the ID of your Mailjet template. -->
        <InputParameter Id="Messages.0.TemplateID" DataType="int" Value="1234567"/>
        <InputParameter Id="Messages.0.TemplateLanguage" DataType="boolean" Value="true"/>
    
        <!-- Update with an email appropriate for your organization. -->
        <InputParameter Id="Messages.0.From.Email" DataType="string" Value="my_email@mydomain.com"/>
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailRequestBody" TransformationClaimType="outputClaim"/>
      </OutputClaims>
    </ClaimsTransformation>
    
  5. 新增下列 Localization 元素。

    <!--
    <BuildingBlocks> -->
      <Localization Enabled="true">
        <SupportedLanguages DefaultLanguage="en" MergeBehavior="ReplaceAll">
          <SupportedLanguage>en</SupportedLanguage>
          <SupportedLanguage>es</SupportedLanguage>
        </SupportedLanguages>
        <LocalizedResources Id="api.custom-email.en">
          <LocalizedStrings>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_subject">Contoso account email verification code</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_message">Thanks for validating the account</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_code">Your code is</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_signature">Sincerely</LocalizedString>
          </LocalizedStrings>
        </LocalizedResources>
        <LocalizedResources Id="api.custom-email.es">
          <LocalizedStrings>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_subject">Código de verificación del correo electrónico de la cuenta de Contoso</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_message">Gracias por comprobar la cuenta de </LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_code">Su código es</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_signature">Sinceramente</LocalizedString>
          </LocalizedStrings>
        </LocalizedResources>
      </Localization>
    <!--
    </BuildingBlocks> -->
    
  6. 更新 ContentDefinitions 元素,以新增 LocalizedResources 元素的參考。

    <!--
    <BuildingBlocks> -->
      <ContentDefinitions>
        <ContentDefinition Id="api.localaccountsignup">
          <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
          <LocalizedResourcesReferences MergeBehavior="Prepend">
            <LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.custom-email.en" />
            <LocalizedResourcesReference Language="es" LocalizedResourcesReferenceId="api.custom-email.es" />
          </LocalizedResourcesReferences>
        </ContentDefinition>
        <ContentDefinition Id="api.localaccountpasswordreset">
          <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
          <LocalizedResourcesReferences MergeBehavior="Prepend">
            <LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.custom-email.en" />
            <LocalizedResourcesReference Language="es" LocalizedResourcesReferenceId="api.custom-email.es" />
          </LocalizedResourcesReferences>
        </ContentDefinition>
      </ContentDefinitions>
    <!--
    </BuildingBlocks> -->
    
  7. 最後,將下列輸入宣告轉換新增至 LocalAccountSignUpWithLogonEmailLocalAccountDiscoveryUsingEmailAddress 技術設定檔。

    <InputClaimsTransformations>
      <InputClaimsTransformation ReferenceId="GetLocalizedStringsForEmail" />
    </InputClaimsTransformations>
    

[選用] 將 UI 當地語系化

Localization 元素可讓您在使用者旅程圖的原則中支援多個地區設定或語言。 原則中的當地語系化支援可讓您同時針對驗證顯示控制項使用者介面元素單次密碼錯誤訊息提供語言特定字串。 將下列 LocalizedString 新增至您的 LocalizedResources。

<LocalizedResources Id="api.custom-email.en">
  <LocalizedStrings>
    ...
    <!-- Display control UI elements-->
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="intro_msg">Verification is necessary. Please click Send button.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="success_send_code_msg">Verification code has been sent to your inbox. Please copy it to the input box below.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="failure_send_code_msg">We are having trouble verifying your email address. Please enter a valid email address and try again.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="success_verify_code_msg">E-mail address verified. You can now continue.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="failure_verify_code_msg">We are having trouble verifying your email address. Please try again.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_send_code">Send verification code</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_verify_code">Verify code</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_send_new_code">Send new code</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_change_claims">Change e-mail</LocalizedString>
    <!-- Claims-->
    <LocalizedString ElementType="ClaimType" ElementId="emailVerificationCode" StringId="DisplayName">Verification Code</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="emailVerificationCode" StringId="UserHelpText">Verification code received in the email.</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="emailVerificationCode" StringId="AdminHelpText">Verification code received in the email.</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="email" StringId="DisplayName">Email</LocalizedString>
    <!-- Email validation error messages-->
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfSessionDoesNotExist">You have exceeded the maximum time allowed.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfMaxRetryAttempted">You have exceeded the number of retries allowed.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfMaxNumberOfCodeGenerated">You have exceeded the number of code generation attempts allowed.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfInvalidCode">You have entered the wrong code.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfSessionConflict">Cannot verify the code, please try again later.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfVerificationFailedRetryAllowed">The verification has failed, please try again.</LocalizedString>
  </LocalizedStrings>
</LocalizedResources>

下一步