Verifikasi email kustom dengan SendGrid

Sebelum memulai, gunakan pemilih Pilih jenis kebijakan untuk memilih jenis kebijakan yang Anda siapkan. Azure Active Directory B2C menawarkan dua metode untuk menentukan cara pengguna berinteraksi dengan aplikasi Anda: melalui alur pengguna yang telah ditentukan sebelumnya atau melalui kebijakan kustom yang sepenuhnya dapat dikonfigurasi. Langkah yang diperlukan dalam artikel ini berbeda untuk setiap metode.

Gunakan surel kustom di Azure Active Directory B2C (AAD B2C) untuk mengirim surel yang disesuaikan kepada pengguna yang mendaftar untuk menggunakan aplikasi Anda. Dengan menggunakan penyedia email pihak ketiga SendGrid, Anda dapat menggunakan templat email Anda sendiri serta alamat dan objek Dari:, serta mendukung pengaturan lokalisasi dan kata sandi sekali pakai kustom (OTP).

Fitur ini tersedia hanya untuk kebijakan kustom. Untuk langkah-langkah penyiapan, pilih Kebijakan kustom dalam pemilih sebelumnya.

Verifikasi email kustom memerlukan penggunaan penyedia email pihak ketiga seperti SendGrid, Mailjet, atau SparkPost, API REST kustom, atau penyedia email berbasis HTTP apa pun (termasuk milik Anda). Artikel ini menjelaskan menyiapkan solusi yang menggunakan SendGrid.

Membuat akun SendGrid

Jika Anda belum memilikinya, mulailah dengan menyiapkan akun SendGrid. Untuk mengetahui petunjuk penyiapan, lihat bagian Membuat Akun SendGrid tentang Cara mengirim email menggunakan SendGrid dengan Azure.

Pastikan Anda menyelesaikan bagian tempat Anda membuat kunci API SendGrid. Rekam kunci API untuk digunakan di langkah selanjutnya.

Penting

SendGrid menawarkan kemampuan untuk mengirim email dari IP bersama dan alamat IP khusus kepada pelanggan. Saat menggunakan alamat IP khusus, Anda perlu membangun reputasi Anda sendiri dengan benar dengan pelatihan alamat IP. Untuk informasi selengkapnya, lihat Pemanasan Alamat Ip.

Membuat kunci kebijakan Azure AD B2C

Selanjutnya, simpan kunci API SendGrid di kunci kebijakan Azure AD B2C agar kebijakan Anda dapat direferensikan.

  1. Masuk ke portal Azure.
  2. Jika Anda memiliki akses ke beberapa penyewa, pilih ikon Pengaturan di menu atas untuk beralih ke penyewa Azure AD B2C Anda dari menu Direktori + langganan.
  3. Di sudut kiri atas portal Azure, pilih Semua layanan, lalu cari dan pilih Azure AD B2C.
  4. Pada halaman Gambaran Umum, pilih Kerangka Kerja Pengalaman Identitas.
  5. Pilih Tombol Kebijakan, lalu pilih Tambahkan.
  6. Untuk Opsi, pilih Manual.
  7. Masukkan Nama untuk kunci kebijakan. Contohnya, SendGridSecret. Awalan B2C_1A_ ditambahkan secara otomatis ke nama kunci Anda.
  8. Di Rahasia, masukkan kunci API SendGrid yang sebelumnya Anda rekam.
  9. Untuk penggunaan Kunci, pilih Tanda tangan.
  10. Pilih Buat.

Membuat templat SendGrid

Dengan akun SendGrid yang dibuat dan kunci API SendGrid yang disimpan dalam kunci kebijakan Azure AD B2C, buat templat transaksional dinamis SendGrid.

  1. Di situs SendGrid, buka halaman templat transaksi lalu pilih Buat Templat Dinamis.

  2. Masukkan nama templat unik seperti Verification email, lalu pilih Buat.

  3. Untuk mulai mengedit templat baru Anda, pilih templat yaitu, Verification email, lalu pilih Tambahkan Versi.

  4. Pilih Templat Kosong lalu Editor Kode.

  5. Di editor HTML, tempelkan templat HTML berikut atau gunakan templat Anda sendiri. Parameter {{otp}} dan {{email}} diganti secara dinamis dengan nilai kata sandi satu kali dan alamat email pengguna.

    <!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">
       <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 {{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: {{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>
    
  6. Perluas menu Pengaturan, dan untuk Nama Versi, masukkan versi templat.

  7. Untuk Subjek, masukkan {{subject}}.

  8. Pilih Simpan.

  9. Kembali ke halaman Templat Transaksional dengan memilih panah belakang.

  10. Rekam ID templat yang Anda buat untuk digunakan di langkah selanjutnya. Contohnya, d-989077fbba9746e89f3f6411f596fb96. Anda menentukan ID ini ketika Anda menambahkan transformasi klaim.

Penting

Langkah selanjutnya menunjukkan kepada Anda cara membuat file XML kebijakan kustom Anda. Sebaiknya Anda menggunakan contoh Verifikasi email khusus kebijakan khusus yang tersedia di GitHub. DisplayControl_TrustFrameworkExtensions.xml menggunakan TrustFrameworkExtensions.xml sebagai file dasarnya oleh karena itu pastikan untuk menyertakan file TrustFrameworkBase.xml, TrustFrameworkLocalization.xml dan TrustFrameworkExtensions.xml dari SocialAndLocalAccountspaket pemula di kebijakan Anda.

Menambahkan jenis klaim AAD B2C

Dalam kebijakan Anda, tambahkan jenis klaim berikut ke elemen <ClaimsSchema> dalam <BuildingBlocks>.

Jenis klaim ini diperlukan untuk menghasilkan dan memverifikasi alamat surel menggunakan kode kata sandi satu kali pakai (OTP).

<!-- 
<BuildingBlocks>
  <ClaimsSchema> -->
    <ClaimType Id="Otp">
      <DisplayName>Secondary One-time password</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
    <ClaimType Id="emailRequestBody">
      <DisplayName>SendGrid 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> -->

Menambahkan transformasi klaim

Selanjutnya, Anda memerlukan transformasi klaim untuk menghasilkan klaim string JSON yang membentuk isi permintaan yang dikirim ke SendGrid.

Struktur objek JSON ditentukan oleh ID dalam notasi titik InputParameters dan TransformationClaimTypes dari InputClaims. Angka dalam notasi titik menyiratkan larik. Nilai berasal dari nilai InputClaims dan properti "Nilai" InputParameters. Untuk informasi selengkapnya tentang transformasi klaim JSON, lihat transformasi klaim JSON.

Tambahkan transformasi klaim berikut ke elemen <ClaimsTransformations> dalam <BuildingBlocks>. Buat pembaruan berikut ini ke XML transformasi klaim:

  • Perbarui nilai InputParameter template_id dengan ID templat transaksional SendGrid yang Anda buat sebelumnya di Membuat templat SendGrid.
  • Perbarui nilai alamat from.email. Gunakan alamat surel yang valid untuk membantu mencegah surel verifikasi ditandai sebagai spam.

    Catatan

    Alamat email ini harus diverifikasi di SendGrid di bawah Autentikasi Pengirim dengan autentikasi domain atau Autentikasi Pengirim Tunggal.

  • Perbarui nilai dari parameter input baris subjek personalizations.0.dynamic_template_data.subject dengan baris subjek yang sesuai untuk organisasi Anda.
<!-- 
<BuildingBlocks>
  <ClaimsTransformations> -->
    <ClaimsTransformation Id="GenerateEmailRequestBody" TransformationMethod="GenerateJson">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.to.0.email" />
        <InputClaim ClaimTypeReferenceId="otp" TransformationClaimType="personalizations.0.dynamic_template_data.otp" />
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.dynamic_template_data.email" />
      </InputClaims>
      <InputParameters>
        <!-- Update the template_id value with the ID of your SendGrid template. -->
        <InputParameter Id="template_id" DataType="string" Value="d-989077fbba9746e89f3f6411f596fb96"/>
        <InputParameter Id="from.email" DataType="string" Value="my_email@mydomain.com"/>
        <!-- Update with a subject line appropriate for your organization. -->
        <InputParameter Id="personalizations.0.dynamic_template_data.subject" DataType="string" Value="Contoso account email verification code"/>
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailRequestBody" TransformationClaimType="outputClaim"/>
      </OutputClaims>
    </ClaimsTransformation>
  <!--
  </ClaimsTransformations>
</BuildingBlocks> -->

Menambahkan definisi konten DataUri

Di bawah transformasi klaim dalam <BuildingBlocks>, tambahkan ContentDefinition berikut untuk mereferensikan URI data versi 2.1.2:

<!--
<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> -->

Membuat DisplayControl

Kontrol tampilan verifikasi digunakan untuk memverifikasi alamat email dengan kode verifikasi yang diterima pengguna.

Contoh kontrol tampilan ini dikonfigurasi untuk:

  1. Kumpulkan jenis klaim alamat email dari pengguna.

  2. Menggunakan tindakan SendCode, buat kode OTP, dan kirim email dengan kode OTP kepada pengguna.

    Send verification code email action

  3. Tunggu hingga pengguna memberikan jenis klaim verificationCode dengan kode yang dikirimkan kepada pengguna.

  4. Tampilkan email kembali ke profil teknis yang ditegaskan sendiri yang memiliki referensi ke kontrol tampilan ini.

Di bawah definisi konten, masih dalam <BuildingBlocks>, tambahkan DisplayControl dari jenis VerificationControl berikut ke kebijakan Anda.

<!--
<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> -->

Menambahkan profil teknis OTP

Profil teknis GenerateOtp menghasilkan kode untuk alamat surel. Profil teknis VerifyOtp memverifikasi kode yang terkait dengan alamat surel. Anda dapat mengubah konfigurasi format dan kedaluwarsa kata sandi satu kali pakai. Untuk informasi selengkapnya tentang profil teknis OTP, lihat Menentukan profil teknis kata sandi satu kali pakai.

Catatan

Kode OTP yang dihasilkan oleh protokol Web.TPEngine.Providers.OneTimePasswordProtocolProvider terkait dengan sesi browser. Artinya, pengguna dapat menghasilkan kode OTP unik dalam sesi browser yang berbeda yang masing-masing valid untuk sesi yang sesuai. Sebaliknya, kode OTP yang dihasilkan oleh penyedia surel bawaan tidak bergantung pada sesi browser. Jadi, jika pengguna menghasilkan kode OTP baru di sesi browser baru, kode tersebut akan menggantikan kode OTP sebelumnya.

Tambahkan profil teknis berikut ke elemen <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> -->

Menambahkan profil teknis REST API

Profil teknis REST API ini menghasilkan konten email (menggunakan format SendGrid). Untuk informasi selengkapnya tentang profil teknis RESTful, lihat Menentukan profil teknis RESTful.

Seperti halnya profil teknis OTP, tambahkan profil teknis berikut ke elemen <ClaimsProviders>.

<ClaimsProvider>
  <DisplayName>RestfulProvider</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="SendOtp">
      <DisplayName>Use SendGrid's 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.sendgrid.com/v3/mail/send</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="ClaimUsedForRequestPayload">emailRequestBody</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_SendGridSecret" />
      </CryptographicKeys>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateEmailRequestBody" />
      </InputClaimsTransformations>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="emailRequestBody" />
      </InputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

Membuat referensi ke DisplayControl

Di langkah terakhir, tambahkan referensi ke DisplayControl yang Anda buat. Timpa profil teknis Anda yang ada serta ditegaskan sendiri LocalAccountSignUpWithLogonEmail dan LocalAccountDiscoveryUsingEmailAddress yang dikonfigurasiKAN dalam kebijakan dasar dengan cuplikan XML berikut. Jika Anda menggunakan versi kebijakan Azure Active Directory B2C yang lebih lama, profil teknis ini menggunakan DisplayClaims dengan referensi ke DisplayControl.

Untuk informasi selengkapnya, lihat Profil teknis yang dibuat sendiri dan 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>

[Opsional] Melokalkan surel Anda

Untuk melokalkan email, Anda harus mengirim string yang di lokal ke SendGrid, atau penyedia email Anda. Misalnya, Anda dapat melokalkan subjek surel, isi, pesan kode, atau tanda tangan surel. Untuk melakukannya, Anda dapat menggunakan transformasi klaim GetLocalizedStringsTransformation untuk menyalin string yang dilokalkan ke dalam jenis klaim. Transformasi klaim GenerateEmailRequestBody, yang menghasilkan payload JSON, menggunakan klaim input yang berisi string yang dilokalkan.

  1. Dalam kebijakan Anda, tentukan klaim string berikut: subjek, pesan, codeIntro, dan tanda tangan.

  2. Tentukan transformasi klaim GetLocalizedStringsTransformation untuk mengganti nilai string yang dilokalkan ke dalam klaim dari langkah 1.

  3. Ubah transformasi klaim GenerateEmailRequestBody untuk menggunakan klaim input dengan cuplikan XML berikut.

  4. Perbarui templat SendGrid Anda untuk menggunakan parameter dinamis sebagai pengganti semua string yang dilokalkan 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="personalizations.0.to.0.email" />
        <InputClaim ClaimTypeReferenceId="subject" TransformationClaimType="personalizations.0.dynamic_template_data.subject" />
        <InputClaim ClaimTypeReferenceId="otp" TransformationClaimType="personalizations.0.dynamic_template_data.otp" />
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.dynamic_template_data.email" />
        <InputClaim ClaimTypeReferenceId="message" TransformationClaimType="personalizations.0.dynamic_template_data.message" />
        <InputClaim ClaimTypeReferenceId="codeIntro" TransformationClaimType="personalizations.0.dynamic_template_data.codeIntro" />
        <InputClaim ClaimTypeReferenceId="signature" TransformationClaimType="personalizations.0.dynamic_template_data.signature" />
      </InputClaims>
      <InputParameters>
        <InputParameter Id="template_id" DataType="string" Value="d-1234567890" />
        <InputParameter Id="from.email" DataType="string" Value="my_email@mydomain.com" />
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailRequestBody" TransformationClaimType="outputClaim" />
      </OutputClaims>
    </ClaimsTransformation>
    
  5. Tambahkan elemen Pelokalan berikut.

    <!--
    <BuildingBlocks> -->
      <Localization Enabled="true">
        <SupportedLanguages DefaultLanguage="en" MergeBehavior="ReplaceAll">
          <SupportedLanguage>en</SupportedLanguage>
          <SupportedLanguage>es</SupportedLanguage>
        </SupportedLanguages>
        <LocalizedResources Id="api.custom-email.en">
          <LocalizedStrings>
            <!--Email template parameters-->
            <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>
            <!--Email template parameters-->
            <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. Tambahkan referensi ke elemen LocalizedResources dengan memperbarui elemen ContentDefinitions.

    <!--
    <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. Terakhir, tambahkan transformasi klaim input berikut ke profil teknis LocalAccountSignUpWithLogonEmail dan LocalAccountDiscoveryUsingEmailAddress.

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

[Opsional] Melokalkan antarmuka pengguna

Elemen Pelokalan memungkinkan Anda untuk mendukung beberapa lokal atau bahasa dalam kebijakan untuk perjalanan pengguna. Dukungan pelokalan dalam kebijakan memungkinkan Anda menyediakan string khusus bahasa komputer untuk Elemen antarmuka pengguna kontrol tampilan verifikasi, dan Pesan kesalahan kata sandi satu kali pakai. Tambahkan LocalizedString berikut ke LocalizedResources Anda.

<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>

Langkah berikutnya