Verificação de email personalizada com Mailjet

Antes de começar, use o seletor Escolher um tipo de política para escolher o tipo de política que você está configurando. O Azure Active Directory B2C oferece dois métodos para definir como os usuários interagem com seus aplicativos: por meio de fluxos dos usuários predefinidos ou de políticas personalizadas totalmente configuráveis. As etapas necessárias neste artigo são diferentes para cada método.

Use o email personalizado no Azure AD B2C (Azure Active Directory B2C) para enviar email personalizado aos usuários que se inscrevem para usar seus aplicativos. Ao usar o provedor de email de terceiros Mailjet, você pode usar seu próprio modelo de email e o De: endereço e assunto, bem como a localização de suporte e as configurações personalizadas de senha de uso único (OTP).

Esse recurso só está disponível para políticas personalizadas. Para obter as etapas de instalação, escolha Política personalizada no seletor anterior.

A verificação de email personalizada requer o uso de um provedor de email de terceiros, como Mailjet, SendGrid ou SparkPost, uma API REST personalizada ou qualquer provedor de email baseado em HTTP (incluindo o próprio). Este artigo descreve como configurar uma solução que usa Mailjet.

Criar uma conta do Mailjet

Se você ainda não tiver uma, comece configurando uma conta do Mailjet (os clientes do Azure podem desbloquear 6.000 emails com um limite de 200 emails/dia).

  1. Siga as instruções de instalação em Criar uma conta do Mailjet.
  2. Para poder enviar emails, registre e valide seu endereço de email ou domínio do remetente.
  3. Navegue até a página de gerenciamento de chaves de API. Registre a Chave de API e a Chave Secreta para uso em uma etapa posterior. As duas chaves são geradas automaticamente quando sua conta é criada.

Importante

O Mailjet oferece aos clientes a capacidade de enviar emails de endereços IP compartilhados e IP dedicados. Ao usar endereços IP dedicados, você precisa criar sua própria reputação corretamente com um aquecimento de endereço IP. Para obter mais informações, consulte Como aquecer meu IP?.

Criar chave de política do Azure AD B2C

Em seguida, armazene a chave de API do Mailjet em uma chave de política do Azure AD B2C para que suas políticas façam referência.

  1. Entre no portal do Azure.
  2. Verifique se você está usando o diretório que contém seu locatário do Azure AD B2C. Selecione o ícone Diretórios + assinaturas na barra de ferramentas do portal.
  3. Na página Configurações do portal | Diretórios + assinaturas, encontre o diretório Azure Active Directory B2C na lista Nome do diretório e, em seguida, selecione Alternar.
  4. Escolha Todos os serviços no canto superior esquerdo do Portal do Azure, pesquise Azure AD B2C e selecione-o.
  5. Na página Visão geral, selecione Identity Experience Framework.
  6. Selecione Chaves de Política e, em seguida, escolha Adicionar.
  7. Para Opções, escolha Manual.
  8. Insira um Nome para a chave de política. Por exemplo, MailjetApiKey. O prefixo B2C_1A_ será adicionado automaticamente ao nome da chave.
  9. Em Segredo, insira a Chave de API do Mailjet que você registrou anteriormente.
  10. Para Uso de chave, selecione Assinatura.
  11. Selecione Criar.
  12. Selecione Chaves de Política e, em seguida, escolha Adicionar.
  13. Para Opções, escolha Manual.
  14. Insira um Nome para a chave de política. Por exemplo, MailjetSecretKey. O prefixo B2C_1A_ será adicionado automaticamente ao nome da chave.
  15. Em Segredo, insira a Chave Secreta do Mailjet que você registrou anteriormente.
  16. Para Uso de chave, selecione Assinatura.
  17. Selecione Criar.

Criar um modelo do Mailjet

Com uma conta do Mailjet criada e a chave de API do Mailjet armazenada em uma chave de política do Azure AD B2C, crie um modelo transacional dinâmico do Mailjet.

  1. No site do Mailjet, abra a página de modelos transacionais e selecione Criar um modelo.

  2. Selecione Codificação em HTML e escolha Código do zero.

  3. Insira um nome de modelo exclusivo como Verification email e selecione Verification email.

  4. No editor de HTML, cole o modelo HTML a seguir ou use um próprio. Os parâmetros {{var:otp:""}} e {{var:email:""}} serão substituídos dinamicamente pelo valor da senha de uso único e pelo endereço de email do usuário.

    <!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>
    <img src="https://mucp.api.account.microsoft.com/m/v2/v?d=AIAACWEPFYXYIUTJIJVV4ST7XLBHVI5MLLYBKJAVXHBDTBHUM5VBSVVPTTVRWDFIXJ5JQTHYOH5TUYIPO4ZAFRFK52UAMIS3UNIPPI7ZJNDZPRXD5VEJBN4H6RO3SPTBS6AJEEAJOUYL4APQX5RJUJOWGPKUABY&amp;i=AIAACL23GD2PFRFEY5YVM2XQLM5YYWMHFDZOCDXUI2B4LM7ETZQO473CVF22PT6WPGR5IIE6TCS6VGEKO5OZIONJWCDMRKWQQVNP5VBYAINF3S7STKYOVDJ4JF2XEW4QQVNHMAPQNHFV3KMR3V3BA4I36B6BO7L4VQUHQOI64EOWPLMG5RB3SIMEDEHPILXTF73ZYD3JT6MYOLAZJG7PJJCAXCZCQOEFVH5VCW2KBQOKRYISWQLRWAT7IINZ3EFGQI2CY2EMK3FQOXM7UI3R7CZ6D73IKDI" width="1" height="1"></body>
    </html>
    
  5. Expanda Editar assunto na parte superior esquerda

    1. Para Assunto, insira um valor padrão. O Mailjet usa esse valor quando a API não contém um parâmetro de assunto.
    2. Para o Nome, digite o nome da sua empresa.
    3. Para o Endereço, selecione seu endereço de email
    4. Selecione Salvar.
  6. Na parte superior direita, selecione Salvar Publicar, e Sim, publicar alterações

  7. Registre a ID do Modelo que você criou para uso em uma etapa posterior. Especifique essa ID ao adicionar a transformação de declarações.

Importante

As próximas etapas mostram como criar os arquivos XML de política personalizada. Recomendamos usar uma política personalizada de verificação de email personalizada de exemplo que está disponível no GitHub. DisplayControl_TrustFrameworkExtensions.xmlusa TrustFrameworkExtensions.xml como arquivo base, portanto, certifique-se de incluir os arquivos TrustFrameworkBase.xml, TrustFrameworkLocalization.xml e TrustFrameworkExtensions.xml do TrustFrameworkExtensions.xmlDisplayControl_TrustFrameworkExtensions.xml em sua política.

Adicionar tipos de declaração do Azure AD B2C

Na sua política, adicione os tipos de declaração a seguir ao elemento <ClaimsSchema> em <BuildingBlocks>.

Esses tipos de declarações são necessários para gerar e verificar o endereço de email usando um código de OTP (senha de uso único).

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

Adicionar transformações de declarações

Em seguida, você precisa de uma transformação de declarações para gerar uma declaração de cadeia de caracteres JSON que será o corpo da solicitação enviada para o Mailjet.

A estrutura do objeto JSON é definida pelas IDs na notação de ponto de InputParameters e TransformationClaimTypes do InputClaims. Os números na notação de ponto implicam matrizes. Os valores são provenientes dos valores de InputClaims e das propriedades de "valor" de InputParameters. Para obter mais informações sobre transformações de declarações JSON, confira Transformações de declarações JSON.

Adicione a transformação de declarações a seguir ao elemento <ClaimsTransformations> em <BuildingBlocks>. Faça as seguintes atualizações para o XML de transformação de declarações:

  • Atualize o valor InputParameter Messages.0.TemplateID com a ID do modelo transacional do Mailjet criado anteriormente em Messages.0.TemplateID.
  • Atualize o valor do endereço Messages.0.From.Email. Use um endereço de email válido para ajudar a impedir que o email de verificação seja marcado como spam.
  • Atualize o valor do parâmetro de entrada da linha do assunto Messages.0.Subject com uma linha de assunto apropriada para sua organização.
<!-- 
<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> -->

Adicionar definição de conteúdo DataUri

Abaixo das transformações de declarações em <BuildingBlocks>, adicione o seguinte <BuildingBlocks> para fazer referência ao URI de dados da versão 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> -->

Criar um DisplayControl

Um controle de exibição de verificação é usado para confirmar o endereço de email com um código de verificação que é enviado ao usuário.

Este exemplo de controle de exibição está configurado para:

  1. Coletar o tipo de declaração de endereço email do usuário.

  2. Aguardar até que o usuário forneça o tipo de declaração verificationCode com o código enviado ao usuário.

  3. Retornar o email para o perfil técnico autodeclarado que tem uma referência a esse controle de exibição.

  4. Usando a ação SendCode, gerar um código de OTP e enviar um email com o código de OTP para o usuário.

    Send verification code email action

Em definições de conteúdo, ainda em <BuildingBlocks>, adicione o <BuildingBlocks> do tipo VerificationControl a seguir à sua política.

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

Adicionar perfis técnicos de OTP

O perfil técnico GenerateOtp gera um código para o endereço de email. O perfil técnico VerifyOtp verifica o código associado ao endereço de email. Você pode alterar a configuração do formato e a expiração da senha de uso único. Para obter mais informações sobre perfis técnicos de OTP, confira Definir um perfil técnico de senha de uso único.

Observação

Códigos OTP gerados pelo protocolo Web.TPEngine.Providers.OneTimePasswordProtocolProvider estão vinculados à sessão do navegador. Isso significa que um usuário pode gerar códigos OTP exclusivos em sessões de navegador diferentes que são válidas para suas sessões correspondentes. Por outro lado, um código OTP gerado pelo provedor de email interno é independente da sessão do navegador, portanto, se um usuário gerar um novo código OTP em uma nova sessão do navegador, ele substituirá o código OTP anterior.

Adicione os perfis técnicos a seguir ao elemento <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">1200</Item>
          <Item Key="CodeLength">6</Item>
          <Item Key="CharacterSet">0-9</Item>
          <Item Key="ReuseSameCode">true</Item>
          <Item Key="NumRetryAttempts">5</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> -->

Adicionar um perfil técnico da API REST

Esse perfil técnico da API REST gera o conteúdo do email (usando o formato do Mailjet). Para obter mais informações sobre perfis técnicos RESTful, confira Definir um perfil técnico RESTful.

Assim como acontece com os perfis técnicos de OTP, adicione os perfis técnicos a seguir ao elemento <ClaimsProviders>.

<ClaimsProvider>
  <DisplayName>RestfulProvider</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="sendOtp">
      <DisplayName>Use email API to send the code the 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>

Fazer uma referência ao DisplayControl

Na etapa final, adicione uma referência ao DisplayControl que você criou. Substitua os perfis técnicos existentes e autodeclarados LocalAccountSignUpWithLogonEmail e LocalAccountDiscoveryUsingEmailAddress que estão configurados na política de base pelo snippet de código XML a seguir. Se você tiver usado uma versão anterior da política do Azure AD B2C, esses perfis técnicos usarão DisplayClaims com uma referência a DisplayControl.

Para obter mais informações, confira Perfil técnico autodeclarado e 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>

[Opcional] Localizar seu email

Para localizar o email, você precisa enviar cadeias de caracteres localizadas ao Mailjet ou ao seu provedor de email. Por exemplo, você pode localizar o assunto do email, o corpo, a mensagem de código ou a assinatura do email. Para fazer isso, use a transformação de declarações GetLocalizedStringsTransformation para copiar cadeias de caracteres localizadas em tipos de declaração. A transformação de declarações GenerateEmailRequestBody, que gera o conteúdo JSON, usa declarações de entrada que contêm as cadeias de caracteres localizadas.

  1. Na sua política, defina as seguintes declarações de cadeia de caracteres: assunto, mensagem, codeIntro e assinatura.

  2. Defina uma transformação de declarações GetLocalizedStringsTransformation para substituir os valores de cadeia de caracteres localizados nas declarações da etapa 1.

  3. Altere a transformação de declarações GenerateEmailRequestBody para usar declarações de entrada com o snippet de código XML a seguir.

  4. Atualize seu modelo do Mailjet para usar parâmetros dinâmicos no lugar de todas as cadeias de caracteres que serão localizadas pelo 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. Adicione o elemento Localization a seguir.

    <!--
    <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. Adicione referências aos elementos LocalizedResources atualizando o elemento 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. Por fim, adicione a transformação de declarações de entrada a seguir aos perfis técnicos LocalAccountSignUpWithLogonEmail e LocalAccountDiscoveryUsingEmailAddress.

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

[Opcional] Localizar a interface do usuário

O elemento Localization permite que você dê suporte a várias localidades ou idiomas na política para os percursos do usuário. O suporte à localização em políticas permite que você forneça cadeias de caracteres específicas a um idioma para os Elementos da interface do usuário do controle de exibição de verificação e as Mensagens de erro de senha de uso único. Adicionar o LocalizedString a seguir a 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>

Próximas etapas