Настройка проверки электронной почты с помощью Mailjet

Для начала с помощью селектора Choose a policy type (Выбрать тип политики) выберите тип пользовательской политики. Azure Active Directory B2C предлагает два метода определения способа взаимодействия пользователей с вашими приложениями: с помощью предопределенных потоков пользователей или полностью настраиваемых пользовательских политик. Действия, которые необходимо выполнить, отличаются для каждого метода.

Используйте функцию настройки сообщений электронной почты в Azure Active Directory B2C, чтобы отправлять электронные письма пользователям, зарегистрированным в вашем приложении. Используя сторонний поставщик электронной почты Mailjet, вы можете использовать свой собственный шаблон электронной почты, адрес От: и тему, а также поддерживать локализацию и настраиваемые параметры одноразового пароля (OTP).

Эта возможность доступна только для пользовательских политик. Чтобы ознакомиться с этапами установки, в предыдущем селекторе выберите Настраиваемая политика.

Для настройки проверки электронной почты требуется использование стороннего поставщика электронной почты, например Mailjet, SendGrid или SparkPost, настраиваемого REST API или любого поставщика электронной почты на основе HTTP (включая свой собственный). В этой статье описывается настройка решения с использованием Mailjet.

Создание учетной записи Mailjet

Если вы не сделали этого ранее, начните с настройки учетной записи Mailjet (клиенты Azure могут разблокировать пакет на 6000 сообщений электронной почты с ограничением 200 сообщений в день).

  1. Следуйте инструкциям по настройке на странице Create a Mailjet Account (Создание учетной записи Mailjet).
  2. Чтобы иметь возможность отправлять электронную почту, зарегистрируйте и проверьте адрес электронной почты отправителя или домен.
  3. Перейдите на страницу API Key Management (Управление ключами API). Запишите Ключ API и Секретный ключ для использования на следующем шаге. Оба ключа генерируются автоматически при создании учетной записи.

Важно!

Mailjet предоставляет клиентам возможность отправки электронной почты с общего IP-адреса и выделенных IP-адресов. При использовании выделенных IP-адресов необходимо правильно создать собственную репутацию путем соответствующей подготовки IP-адреса. Дополнительные сведения см. в разделе How do I warm up my IP? (Как подготовить мой IP-адрес?)

Создание ключа политики Azure Active Directory B2C

Затем сохраните ключ API Mailjet в ключе политики Azure Active Directory B2C, чтобы создать ссылку на политики.

  1. Войдите на портал Azure.
  2. Если у вас есть доступ к нескольким клиентам, выберите значок Параметры в верхнем меню, чтобы переключиться на клиент Azure AD B2C из меню каталогов и подписок.
  3. Выберите Все службы в левом верхнем углу окна портала Azure, а затем найдите и выберите Azure AD B2C.
  4. На странице Обзор выберите Identity Experience Framework.
  5. Выберите Ключи политики, а затем щелкните Добавить.
  6. Для пункта Параметры выберите Вручную.
  7. Введите имя ключа политики. Например, MailjetApiKey. Префикс B2C_1A_ будет автоматически добавлен к имени ключа.
  8. В поле Секрет введите сохраненный ранее Ключ API Mailjet.
  9. Чтобы использовать параметр Ключ, выберите Подпись.
  10. Выберите Создать.
  11. Выберите Ключи политики, а затем щелкните Добавить.
  12. Для пункта Параметры выберите Вручную.
  13. Введите имя ключа политики. Например, MailjetSecretKey. Префикс B2C_1A_ будет автоматически добавлен к имени ключа.
  14. В поле Секрет введите сохраненный ранее секретный ключ Mailjet.
  15. Чтобы использовать параметр Ключ, выберите Подпись.
  16. Выберите Создать.

Создание шаблона Mailjet

После создания учетной записи Mailjet и ключа API Mailjet, сохраненного в ключе политики Azure Active Directory B2C, создайте динамический шаблон транзакций Mailjet.

  1. На веб-сайте Mailjet откройте страницу Transactional templates (Шаблоны транзакций) и нажмите Create a new template (Создать новый шаблон).

  2. Выберите By coding it in HTML (Написать на HTML), а затем выберите Code from scratch (Написать с нуля).

  3. Введите уникальное имя шаблона, например Verification email, и нажмите кнопку Create (Создать).

  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. В поле Тема введите значение по умолчанию. Mailjet использует это значение, если в API не указана тема.
    2. В поле Имя введите название вашей компании.
    3. В поле Адрес выберите свой адрес электронной почты.
    4. Выберите Сохранить.
  6. В правой верхней части выберите Сохранить и опубликовать, затем нажмите Да, опубликовать изменения.

  7. Запишите Идентификатор шаблона, созданного для использования на последующих шагах. Этот идентификатор указывается при добавлении преобразования утверждений.

Важно!

В следующих шагах показано, как создавать XML-файлы настраиваемой политики. Мы рекомендуем использовать пример настраиваемой политики проверки электронной почты, доступный на GitHub. DisplayControl_TrustFrameworkExtensions.xml использует TrustFrameworkExtensions.xml в качестве базового файла, поэтому не забудьте включить в свою политику файлы TrustFrameworkBase.xml, TrustFrameworkLocalization.xml и TrustFrameworkExtensions.xml из SocialAndLocalAccountsначальный пакет.

Добавление типов утверждений Azure Active Directory B2C

В политике добавьте следующие типы утверждений в элемент <ClaimsSchema> внутри <BuildingBlocks>.

Эти типы утверждений требуются для создания и проверки адреса электронной почты с использованием кода одноразового пароля (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 определяется идентификаторами в точечной нотации InputParameters и TransformationClaimTypes в InputClaims. Числа в точечной нотации представляют массивы. Значения берутся из значений InputClaims и свойств "Value" для InputParameters. Дополнительные сведения о преобразовании утверждений JSON см. в статье Преобразования утверждений JSON.

Добавьте следующее преобразование утверждений в элемент <ClaimsTransformations> внутри <BuildingBlocks>. Внесите следующие изменения в XML-код преобразования утверждений.

  • Обновите Messages.0.TemplateID значение InputParameter, указав идентификатор шаблона транзакций Mailjet, который вы создали ранее в разделе Создание шаблона Mailjet.
  • Обновите значение адреса 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 для ссылки на URI данных версии 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> -->

Создание DisplayControl

Элемент управления отображением подтверждения используется для подтверждения адреса электронной почты с использованием кода подтверждения, который отправляется пользователю.

Этот пример элемента управления отображением настроен следующим образом.

  1. Получите от пользователя тип утверждения адреса email.

  2. Создание кода OTP с помощью действия SendCode и отправка пользователю сообщения электронной почты с кодом OTP.

    Send verification code email action

  3. Ожидание, пока пользователь укажет тип утверждения verificationCode с кодом, отправленным пользователю.

  4. Возврат email к самоутвержденному техническому профилю со ссылкой на этот элемент управления отображением.

В разделе определений содержимого внутри <BuildingBlocks> добавьте в свою политику DisplayControl типа VerificationControl.

<!--
<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 см. в статье Определение технического профиля с одноразовым паролем.

Примечание.

Коды OTP, которые создаются с применением протокола Web.TPEngine.Providers.OneTimePasswordProtocolProvider, привязаны к сеансу браузера. Это означает, что пользователь может создавать уникальные коды 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. Переопределите существующие самостоятельно утвержденные технические профили LocalAccountSignUpWithLogonEmail и LocalAccountDiscoveryUsingEmailAddress, которые настроены в базовой политике, с помощью приведенного ниже фрагмента XML-кода. Если вы использовали более раннюю версию политики Azure AD B2C, эти технические профили используют DisplayClaims со ссылкой на DisplayControl.

Дополнительные сведения см. в статье Самоутвержденный технический профиль и 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 для копирования локализованных строк в типы утверждений. Преобразование утверждений GenerateEmailRequestBody, создающее полезные данные JSON, использует входные утверждения, содержащие локализованные строки.

  1. В политике определите следующие строковые утверждения: subject, message, codeIntro и signature.

  2. Определите преобразование утверждений GetLocalizedStringsTransformation, чтобы заменить локализованные строковые значения на утверждения из шага 1.

  3. Измените преобразование утверждений GenerateEmailRequestBody, чтобы использовать входные утверждения, как в следующем фрагменте кода XML.

  4. Обновите шаблон Mailjet, чтобы использовать динамические параметры вместо всех строк, которые будут локализованы с помощью Azure Active Directory 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. Добавьте следующий элемент локализации.

    <!--
    <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. Добавьте ссылки на элементы LocalizedResources, обновив элемент 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. Наконец, добавьте следующее преобразование входных утверждений в технические профили LocalAccountSignUpWithLogonEmail и LocalAccountDiscoveryUsingEmailAddress.

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

[Необязательно] Локализация пользовательского интерфейса

Элемент 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>

Следующие шаги